package com.alibaba.citrus.cr.b2b.trade.order.facade.service;

import com.alibaba.citrus.cr.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.cr.b2b.trade.order.facade.common.StringConverter;
import com.alibaba.citrus.cr.b2b.trade.order.functions.order.entity.OrderWriteEntity;
import com.alibaba.citrus.cr.b2b.trade.order.functions.order.factory.OrderWriteFactory;
import com.alibaba.citrus.cr.b2b.trade.order.functions.utils.OrderOutCodeAssmeble;
import com.alibaba.citrus.cr.b2b.trade.order.functions.utils.SaveOrderConverter;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderLineQueryServiceRepository;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderLineWriteRepository;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderQueryServiceRepository;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderWriteRepository;
import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.annotation.ProcessInvoker;
import com.alibaba.citrus.cr.common.constant.SaleOrderConstants;
import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.lock.RedisLock;
import com.alibaba.citrus.cr.common.lock.SaleRedisLock;
import com.alibaba.citrus.cr.common.log.ModuleEnum;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.common.util.TimeUtil;
import com.alibaba.cz.base.tool.DateFormatUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogModel;
import com.alibaba.cz.base.tool.log.model.OperateType;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.db.service.CustomSequenceAccessor;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.platform_enhance.SaleOrderTag;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crb2btradecenter.api.orderwrite.dto.BatchSubmitSaleOrderRequest;
import com.epoch.app.crb2btradecenter.api.orderwrite.dto.*;
import com.epoch.app.crb2btradecenter.api.orderwrite.service.OrderWriteService;
import com.epoch.app.crb2btradecenter.domain.order.dto.QueryByOrderBizIdsRequest;
import com.epoch.app.crb2btradecenter.domain.order.dto.UpdateFeaturesResponse;
import com.epoch.app.crb2btradecenter.domain.order.model.Order;
import com.epoch.app.crb2btradecenter.domain.order.service.OrderService;
import com.epoch.app.crb2btradecenter.dto.OrderDetailDTO;
import com.epoch.app.crb2btradecenter.dto.request.OrderPageQueryRequest;
import com.epoch.app.crb2btradecenter.dto.request.*;
import com.epoch.app.crb2btradecenter.dto.response.BatchCreateOrderResponse;
import com.epoch.app.crb2btradecenter.dto.response.OrderPageQueryResponse;
import com.epoch.app.crb2btradecenter.dto.response.OrderQueryResponse;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.crb2btradecenter.messagetask.dto.CreateResponse;
import com.epoch.app.crb2btradecenter.messagetask.model.MessageTask;
import com.epoch.app.crb2btradecenter.messagetask.service.MessageTaskService;
import com.epoch.app.crb2btradecenter.model.dto.*;
import com.epoch.app.crb2btradecenter.model.enums.MessageTaskTypeEnum;
import com.epoch.app.crb2btradecenter.model.enums.OrderOperateType;
import com.epoch.app.crb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.crb2btradecenter.sdo.OrderSDO;
import com.epoch.app.crb2btradecenter.sdo.ScItemSDO;
import com.epoch.app.crforecastsales.api.forecastorderlinequery.service.ForecastOrderLineQueryService;
import com.epoch.app.crforecastsales.model.dto.QueryGoodsDetailForMiniprogrameRequest;
import com.epoch.app.crforecastsales.model.dto.QueryGoodsDetailForMiniprogrameResponse;
import com.epoch.app.crforecastsales.model.dto.QuerySaleUnitRequest;
import com.epoch.app.crforecastsales.model.dto.SelectCombox;
import com.epoch.app.crforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.crforecastsales.service.CrForecastSalesService;
import com.epoch.app.crplatformenhance.api.customeraddressquery.service.CustomerAddressQueryService;
import com.epoch.app.crplatformenhance.api.customerquery.service.CustomerQueryService;
import com.epoch.app.crplatformenhance.api.group.scitemgroupquery.service.ScItemGroupQueryService;
import com.epoch.app.crplatformenhance.api.organizationquery.dto.GetOrganizationsByOutCodesRequest;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.api.strategyquery.dto.QueryGenerateOrderSwitchRequest;
import com.epoch.app.crplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.crplatformenhance.channel.service.ChannelService;
import com.epoch.app.crplatformenhance.dto.request.*;
import com.epoch.app.crplatformenhance.dto.response.ScItemGroupResponse;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.crplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.crplatformenhance.model.dto.ChannelResponse;
import com.epoch.app.crplatformenhance.model.dto.GetOrgChannelRelationByOrgId2Request;
import com.epoch.app.crplatformenhance.model.dto.OrganizationChannelRelationSDO;
import com.epoch.app.crplatformenhance.model.dto.QueryChannelRequest;
import com.epoch.app.crplatformenhance.model.enums.ScItemManageRangeStatus;
import com.epoch.app.crplatformenhance.scitemmanagerange.model.ScItemManageRange;
import com.epoch.app.crplatformenhance.scitemmanagerangeread.service.ScItemManageRangeReadService;
import com.epoch.app.crplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.crplatformenhance.sdo.CustomerSDO;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.crunifiedinventory.api.allocateorderread.service.AllocateOrderReadService;
import com.epoch.app.crunifiedinventory.api.allocaterelationread.dto.QueryAllocateRelationForOrderRequest;
import com.epoch.app.crunifiedinventory.api.allocaterelationread.service.AllocateRelationReadService;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.model.AllocateApplyOrder;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.service.AllocateApplyOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.AllocateApplyOrderDetailLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.model.AllocateApplyOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.service.AllocateApplyOrderDetailService;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.AllocateOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.DeleteAllocateOrderRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.crunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.AllocateOrderDetailLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.DeleteAllocateOrderDetailRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderDetailsQueryRequest;
import com.epoch.app.crunifiedinventory.dto.response.AllocateOrderDetailsQueryResponse;
import com.epoch.app.crunifiedinventory.model.dto.GetListWarehouseStockRequest;
import com.epoch.app.crunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.crunifiedinventory.sdo.AllocateRelationSDO;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateApplyOrderStatusEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateStatusEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.DocumentReasonEnum;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import com.epoch.app.mnordercenter.model.dto.CommonAsyncMessageResponse;
import com.epoch.app.mnordercenter.model.dto.PushOrderInfoToMnSideRequestOrderInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.alibaba.citrus.cr.common.constant.SaleOrderConstants.TAG_ORDER_CENTER;

@Component
@Primary
public class OrderWriteServiceImpl implements OrderWriteService {

    private static final Log log = Log.getLogger(OrderWriteServiceImpl.class);

    private static final String CACHE_CODE = "REDIS_CACHE";
    /**
     * 获取锁的超时时间（毫秒）
     */
    private static final long TIMEOUT_MSECS = 2 * 60 * 1000;
    /**
     * 锁过期时间（毫秒）
     */
    private static final long EXPIRE_MSECS = 10 * 60 * 1000;
    /**
     * 循环获取锁的间隔时间（毫秒）
     */
    private static final long INTERNAL = 2000;

    private static final List<String> LINE_PRICE_NO_LIMIT = Lists.newArrayList(
            SaleOrderTag.FREE_ORDER.getCode(),
            SaleOrderTag.CASH_ORDER.getCode(),
            SaleOrderTag.EXCHANGE_ORDER.getCode(),
            SaleOrderTag.STD_RETURN_ORDER.getCode(),
            SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode(),
            SaleOrderTag.DS_STD_RETURN_ORDER.getCode()
    );
    public static final String SAP_SYNC = "sapSync:";
    private static final String RETURN_FLAG = "1";

    @Autowired
    private BaseDataService baseDataService;
    @Resource
    private OrderQueryServiceRepository orderQueryServiceRepository;
    @Autowired
    private AllocateOrderReadService allocateOrderReadService;
    @Resource
    private OrderWriteRepository orderWriteRepository;
    @Resource
    private CustomerAddressQueryService customerAddressQueryService;
    @Resource
    private OrganizationQueryService organizationQueryService;
    @Resource
    private ChannelService channelService;
    @Resource
    private ScItemGroupQueryService scItemGroupQueryService;
    @Resource
    private CustomerQueryService customerQueryService;
    @Resource
    private OrderLineWriteRepository orderLineWriteRepository;
    @Resource
    private OrderLineQueryServiceRepository orderLineQueryServiceRepository;
    @Resource
    private BcOrderService bcOrderService;
    @Resource
    private UnifiedInventoryService unifiedInventoryService;
    @Resource
    private CrUnifiedInventoryService crUnifiedInventoryService;
    @Resource
    private ForecastOrderLineQueryService forecastOrderLineQueryService;
    @Resource
    private CrForecastSalesService crForecastSalesService;
    @Resource
    private StrategyQueryService strategyQueryService;
    @Resource
    private EpochMessageService messageService;
    @Resource
    private CrPlatformEnhanceService crPlatformEnhanceService;
    @Resource
    private AllocateRelationReadService allocateRelationReadService;
    @Resource
    private EpochCacheService epochCacheService;
    @Resource
    private AllocateOrderService allocateOrderService;
    @Resource
    private AllocateOrderDetailService allocateOrderDetailService;
    @Resource
    private AllocateApplyOrderService allocateApplyOrderService;
    @Resource
    private AllocateApplyOrderDetailService allocateApplyOrderDetailService;
    @Resource
    private MessageTaskService messageTaskService;
    @Resource
    private CustomSequenceAccessor customSequenceAccessor;
    @Resource
    private ScItemManageRangeReadService scItemManageRangeReadService;
    @Resource
    private OrderService orderService;
    @Resource
    EpochMessageService epochMessageService;
    private static final Pattern PATTERN_NUMERIC = Pattern.compile("^-{0,1}[0-9]+([.]{1}[0-9]+){0,1}$");

    private static final Pattern PATTERN_SPECIAL_STRING = Pattern.compile("[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t");

    @FacadeInvoker
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    @Override
    public Result<List<BatchCreateOrderResponse>> saveSaleOrder(SaveSaleOrderRequest request) {
        log.info("OrderServiceImpl SaveSaleOrderRequest:" + JSON.toJSONString(request));
        if (request == null) {
            log.error("创建销售订单入参为空");
            return Result.fail("OTS-05-001-10-16-028", "参数不能为空");
        }
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();

        List<BatchCreateOrderResponse> batchCreateOrderResponsesNew = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(request.getOrderSDOS())) {
            request.getOrderSDOS().forEach(x -> {
                if(StringUtils.isBlank(x.getFromSys())) {
                    x.setFromSys("APP_OTS");
                }
                if(StringUtils.isBlank(x.getBisUnitCode())) {
                    x.setBisUnitCode(request.getBisUnitCode());
                }
            });
            //构造销售订单实体
            List<OrderWriteEntity> orderWriteEntityList = OrderWriteFactory.createOrder(request);
            for (OrderWriteEntity orderWriteEntity : orderWriteEntityList) {
                OrderOutCodeAssmeble.assembleOutCode(orderWriteEntity.getOrderSDO());
                //创建销售订单，方法里进行了模型转换
                List<BatchCreateOrderResponse> batchCreateOrderResponses = orderWriteEntity.batchSave(employeeGetCurrentLoginResponse);
                batchCreateOrderResponsesNew.addAll(batchCreateOrderResponses);
            }
            return Result.success(batchCreateOrderResponsesNew);
        }

        //构造销售订单实体，方法里进行了模型转换
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.saveSaleOrder(request);
        if(StringUtils.isBlank(orderWriteEntity.getOrderSDO().getFromSys())) {
            orderWriteEntity.getOrderSDO().setFromSys("APP_OTS");
        }
        if(StringUtils.isBlank(orderWriteEntity.getOrderSDO().getBisUnitCode())) {
            orderWriteEntity.getOrderSDO().setBisUnitCode(request.getBisUnitCode());
        }
        OrderOutCodeAssmeble.assembleOutCode(orderWriteEntity.getOrderSDO());
        //创建销售订单
        String id = orderWriteEntity.save();

        //记录日志
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(id);
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.CREATE.getOperateType());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            opLogModel.setOperatorId(employeeGetCurrentLoginResponse.getEmployeeId());
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.CREATE.getDesc());
        map.put("bizNo", orderWriteEntity.getOrderSDO().getOrderBizId());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(orderWriteEntity.getOrderSDO().getOrderType())){
            SaleOrderTag saleOrderTag = SaleOrderTag.of(orderWriteEntity.getOrderSDO().getOrderType());
            if (Objects.nonNull(saleOrderTag)){
                map.put("orderType",saleOrderTag.getDesc());
            }
        }
        if (Objects.nonNull(orderWriteEntity.getOrderSDO().getStatus())){
            OrderStatus orderStatus = OrderStatus.of(orderWriteEntity.getOrderSDO().getStatus());
            if (Objects.nonNull(orderStatus)){
                map.put("status",orderStatus.getDesc());
            }
        }
        opLogModel.setFeatures(JSON.toJSONString(map));
        log.asyncMonitorObjectChangeV2(opLogModel);

        BatchCreateOrderResponse response = new BatchCreateOrderResponse();
        response.setOrderId(id);
        batchCreateOrderResponsesNew.add(response);
        return Result.success(batchCreateOrderResponsesNew);
    }

    @Override
    @FacadeInvoker
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots")
    public Result<Boolean> modifySaleOrder(ModifyOrderRequest request) {
        log.info("OrderServiceImpl#modifySaleOrder request={}", JSON.toJSONString(request));
        return modifySaleOrderV2(request);
    }

    public Result<Boolean> modifySaleOrderV2(ModifyOrderRequest request) {
        log.info("OrderServiceImpl#modifySaleOrderV2 request={}", JSON.toJSONString(request));

        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
        OrderQueryRequest queryRequest = new OrderQueryRequest();
        //sap同步015
        if (StringUtils.isBlank(request.getOutOrderId())) {
            // 页面修改无销售单id、无需加锁
            if (null == request.getBaseInfo() || StringUtils.isBlank(request.getBaseInfo().getId())) {
                return Result.fail("OTS-05-001-10-16-031", "页面入参不能为空");
            }
            //2022.11.16 页面修改 当订单已经提交后不能再提交
            queryRequest.setId(request.getBaseInfo().getId());
            OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
            return updateSaleOrderInfo(query, request, employeeGetCurrentLoginResponse);
        }

        String lockKey = SAP_SYNC + request.getOutOrderId();
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, INTERNAL)) {
            if (!lock.lock()) {
                log.error("modifySaleOrderV2未获取到锁|外部单号为:" + lockKey);
                return Result.fail("OTS-04-001-00-15-059", "modifySaleOrderV2未获取到锁|外部单号为:" + lockKey);
            }
            log.info("ThreadId:" + Thread.currentThread().getId() + "|SaleRedis.key=" + lockKey + "|lock");
            PageResult<List<OrderPageQueryResponse>> listPageResult = null;
            if (StringUtils.isNotBlank(request.getTradeOrderId())) {
                OrderPageQueryRequest pageQueryRequest = new OrderPageQueryRequest();
                pageQueryRequest.setId(request.getTradeOrderId());
                listPageResult = orderQueryServiceRepository.pageQuery(pageQueryRequest);
            }
            if (Objects.isNull(listPageResult) || CollectionUtils.isEmpty(listPageResult.getContent())) {
                OrderPageQueryRequest innerQuery = new OrderPageQueryRequest();
                innerQuery.setOuterOrderId(request.getOutOrderId());
                listPageResult = orderQueryServiceRepository.pageQuery(innerQuery);
            }
            //查询不到就创建
            if (Objects.isNull(listPageResult) || CollectionUtils.isEmpty(listPageResult.getContent())) {
                OrderSDO orderSDO = new OrderSDO();
                Date date = new Date();
                //构建订单
                extracted(request, orderSDO, "create");
                orderSDO.setCreatorName(request.getCreator());
                orderSDO.setModifierId(request.getModifier());
                orderSDO.setGmtCreate(date);
                orderSDO.setSyncVersion(0);
                //针对SAP创建订单通过013回调，需要补充的字段
                orderSDO.setBusinessUnitOutCode(request.getSaleOrganizationCode());
                orderSDO.setFulfillmentPriority(request.getFulfillmentPriority());
                orderSDO.setFulfillmentTypeCode(request.getFulfillmentTypeCode());
                orderSDO.setAutoFulfillment(request.getAutoFulfillment());
                orderSDO.setOrderChannelCode(request.getOrderChannelCode());
                orderSDO.setChannelOutCode(request.getSapChannel());
                orderSDO.setOrderTypeName(SalesOrderTypeEnum.descByCode(request.getOrderType()));
                orderSDO.setWareHouseOutCode(request.getWareHouseOutCode());
                orderSDO.setOrderCategoryCode(OrderCategoryEnum.GROUP.getCode());
                if (SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                        || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                        || SaleOrderTag.DS_STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())
                        || ReturnOrderTypeEnum.RE_ORDER_GROUP.getCode().equals(orderSDO.getOrderType())
                        || ReturnOrderTypeEnum.RE_ORDER_FREE_GROUP.getCode().equals(orderSDO.getOrderType())) {
                    orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
                } else if (SaleOrderTag.EXCHANGE_ORDER.getCode().equals(orderSDO.getOrderType())) {
                    orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
                } else {
                    orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                }
                SetOrderTag.getOrderTag(orderSDO.getOrderType(), orderSDO);
                orderSDO.getOrderLineSDOS().forEach(orderLineSDO -> {
                    orderLineSDO.setStatus(orderSDO.getStatus());
                    if (StringUtils.isEmpty(orderLineSDO.getOrderLineTag())) {
                        orderLineSDO.setOrderLineTag(orderSDO.getOrderTag());
                    }
                    orderLineSDO.setGmtCreate(date);
                });
                if (StringUtils.isNotBlank(request.getFromSys())) {
                    orderSDO.setFromSys(request.getFromSys());
                } else {
                    orderSDO.setFromSys("APP_OTS");
                }
                OrderWriteEntity orderWriteEntity = OrderWriteFactory.saveOrderZRE3(orderSDO);
                OrderOutCodeAssmeble.assembleOutCode(orderWriteEntity.getOrderSDO());
                orderWriteEntity.batchSave(employeeGetCurrentLoginResponse);
                sendOrderMessage(orderSDO);
                return Result.success(true);
            }
            queryRequest.setId(listPageResult.getContent().get(0).getId());
            OrderQueryResponse query = orderQueryServiceRepository.query(queryRequest);
            return updateSaleOrderInfo(query, request, employeeGetCurrentLoginResponse);
        } catch (Exception e) {
            log.error("modifySaleOrderV2数据异常:", e);
            throw e;
        }
    }

    private void sendOrderMessage(OrderSDO orderSDO) {
        try {
            // 发送MQ消息通知其他中心
            CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
            commonAsyncMessageResponse.setEventCode(InnerMessageEventEnum.SALES_ORDER_CREATED_SAP.getValue());
            commonAsyncMessageResponse.setEventName(InnerMessageEventEnum.SALES_ORDER_CREATED_SAP.getLabel());
            commonAsyncMessageResponse.setData(Lists.newArrayList(orderSDO));
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
            log.info("OrderServiceImpl sendOrderMessage commonAsyncMessageResponse= {},map={}", JSON.toJSONString(commonAsyncMessageResponse),JSON.toJSONString(map));
            Boolean result = epochMessageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SalesOrderEvent",orderSDO.getOrderBizId(),JSONObject.toJSONString(commonAsyncMessageResponse),map);
            log.info("OrderServiceImpl sendOrderMessage  result={}",result);
        }catch (Exception e){
            log.error("OrderServiceImpl sendOrderMessage  error ",e);
        }

    }

    public Result<Boolean> modifySaleOrderSimple(OrderSDO orderSDO) {
        log.info("OrderServiceImpl#modifySaleOrderV2 orderSDO={}", JSON.toJSONString(orderSDO));
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> result = orderWriteEntity.modify();
        log.info("OrderServiceImpl#modifySaleOrderSimple result={}", result);
        return result;
    }

    //当order有子单数据的时候,页面提交的参数理论上不能少于现有的,因为页面删除货品是真实删除
    void checkPageParams(ModifyOrderRequest request, OrderSDO orderSDO) {
        Set<String> requestOrderDetailIds = Sets.newHashSet();
        Set<String> orderLineIds = Sets.newHashSet();
        if (request != null && CollectionUtils.isNotEmpty(request.getOrderDetailList())) {
            requestOrderDetailIds = request.getOrderDetailList().stream()
                    .filter(x -> org.apache.commons.lang3.StringUtils.isNotBlank(x.getId()))
                    .map(OrderLineSaveInnerRequest::getId)
                    .collect(Collectors.toSet());
        }
        if (orderSDO != null && CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
            orderLineIds = orderSDO.getOrderLineSDOS().stream()
                    .map(OrderLineSDO::getId).collect(Collectors.toSet());
        }
        final Set<String> requestSet = requestOrderDetailIds;
        boolean match = orderLineIds.containsAll(requestSet) && requestSet.containsAll(orderLineIds);
        if (!match) {
            throw new FacadeException("OTS-05-001-10-16-052");
        }
    }

    public Result<Boolean> updateSaleOrderInfo(OrderQueryResponse order, ModifyOrderRequest request,
                                               EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {
        log.info("OrderService#updateSaleOrderInfo order={}", JSON.toJSONString(order));
        log.info("OrderService#updateSaleOrderInfo request={}", JSON.toJSONString(request));

        OrderSDO orderSDO =  SaveOrderConverter.respConverterSDO(order);
        OrderSDO oldOrderSDO =  SaveOrderConverter.respConverterSDO(order);


        if (request.getBaseInfo() != null) {
            //页面参数转换
            //2022.11.16 修改 页面参数交换时行号丢失 页面修改 当订单已经提交后不能再提交
            checkPageParams(request, orderSDO);
            extracted1(request, orderSDO);
        } else {
            //015参数转换
            log.info("OrderService updateSaleOrderInfo before extracted orderSDO={}", JSON.toJSONString(orderSDO));
            extracted(request, orderSDO, "update");
            log.info("OrderService updateSaleOrderInfo after extracted orderSDO={}", JSON.toJSONString(orderSDO));
            // os等于OrderCenter时，不更新订单状态
            if (!ObjectUtils.isEmpty(orderSDO.getFeatures()) && TAG_ORDER_CENTER.equals(orderSDO.getFeatures().get("os"))) {
                orderSDO.setModifierId(request.getModifier());
                orderSDO.setModifierName(request.getCreator());
            }
        }
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        //015销售单更新进行外部编码补全
        OrderOutCodeAssmeble.assembleOutCode(orderWriteEntity.getOrderSDO());
        Result<Boolean> fag = orderWriteEntity.modify();
        //识别拒绝的子单并发送拒绝消息
        this.getRefusedId(oldOrderSDO, orderSDO);
        doOperateLog(orderSDO, employeeGetCurrentLoginResponse, OrderOperateType.EDIT);
        return fag;
    }

    /**
     * 获取修改前后，新拒绝的子单有哪些
     *
     * @param oldOrderSDO
     * @param orderSDO
     * @return
     */
    private List<String> getRefusedId(OrderSDO oldOrderSDO, OrderSDO orderSDO) {
        List<OrderLineSDO> oldOrderLines = oldOrderSDO.getOrderLineSDOS();
        List<OrderLineSDO> newOrderLines = orderSDO.getOrderLineSDOS();
        if (CollectionUtils.isEmpty(oldOrderLines)) {
            return null;
        }
        Map<String, String> oldMap = oldOrderLines.stream().filter(orderLineSDO -> StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode()))
                .collect(Collectors.toMap(OrderLineSDO::getId, OrderLineSDO::getRefuseReasonCode));

        List<String> newRefuseIds = newOrderLines.stream().filter(orderLineSDO ->
                        (StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode()) && !oldMap.containsKey(orderLineSDO.getId())))
                .map(OrderLineSDO::getId)
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(newRefuseIds)) {
            TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
            tradeMessageSDO.setOrderSDO(orderSDO);
            tradeMessageSDO.setAffectLineIds(newRefuseIds);
            String message = JSON.toJSONString(tradeMessageSDO);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
            log.info("orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
            messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleRefused", orderSDO.getOrderBizId(), message, map);
        }
        return newRefuseIds;

    }

    private void extracted1(ModifyOrderRequest request, OrderSDO orderSDO) {
        SaveSaleOrderRequest baseInfo = request.getBaseInfo();
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
        if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
            orderSDO.setModifierId(employeeGetCurrentLoginResponse.getEmployeeId());
            orderSDO.setModifierName(employeeGetCurrentLoginResponse.getEmployeeName());
        }
        orderSDO.setId(baseInfo.getId());
        if (StringUtils.isNotBlank(baseInfo.getOrderType())){
            orderSDO.setOrderType(baseInfo.getOrderType());
        }
        orderSDO.setOrderTypeName(baseInfo.getOrderTypeName());
        orderSDO.setReceiveAddressCode(baseInfo.getDeliveryAddr());
        orderSDO.setCustomerAccounts(baseInfo.getCustomerAccounts());
        orderSDO.setCustomerCode(baseInfo.getCustomerCode());
        orderSDO.setCustomerName(baseInfo.getCustomerName());
        orderSDO.setWareHouseCode(baseInfo.getShippingWarehouse());
        //2023.02.27
        orderSDO.setReceiveWareHouseCode(baseInfo.getReceiveWareHouseCode());
        //这里从收货仓编码转换一下
        if (StringUtils.isNotBlank(baseInfo.getReceiveWareHouseCode())) {
            QueryWarehouseByIdRequest queryCargoZoneByIdRequest = new QueryWarehouseByIdRequest();
            queryCargoZoneByIdRequest.setId(baseInfo.getReceiveWareHouseCode());
            Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(queryCargoZoneByIdRequest);
            if (warehouseInfoResult != null && warehouseInfoResult.getResult() != null) {
                orderSDO.setReceiveWareHouseName(warehouseInfoResult.getResult().getName());
            }
        }
        orderSDO.setOrganizationCode(baseInfo.getSalesOrganization());
        orderSDO.setChannelCode(baseInfo.getBuzChannel());
        orderSDO.setChannelName(baseInfo.getBuzChannelName());
        orderSDO.setSaleChannelCode(baseInfo.getSaleChannel());
        orderSDO.setSaleChannelName(baseInfo.getSaleChannelName());
        orderSDO.setDepartmentCode(baseInfo.getSaleDepartment());
        orderSDO.setDepartmentName(baseInfo.getSaleDepartmentName());
        orderSDO.setCustomerName(baseInfo.getCustomerName());
        orderSDO.setOrganizationName(baseInfo.getSalesOrganizationName());

        orderSDO.setCostCenter(baseInfo.getCostCenter());
        orderSDO.setCashCustomerName(baseInfo.getCashCustomerName());
        orderSDO.setCustomerReferenceNumber(baseInfo.getCustomerRefNo());
        orderSDO.setRemark(baseInfo.getRemark());
        orderSDO.setProductGroupCode(baseInfo.getGoodsGroup());
        orderSDO.setProductGroupName(baseInfo.getGoodsGroupName());
        if (StringUtils.isNotBlank(baseInfo.getUpdateTime())) {
            orderSDO.setGmtModified(DateFormatUtil.parseSimpleDateFormat(baseInfo.getUpdateTime()));
        }
        orderSDO.setCreateReason(baseInfo.getOrderReason());
        orderSDO.setCreatorId(baseInfo.getCreatorId());
        orderSDO.setCreatorName(baseInfo.getCreator());
        if (StringUtils.isNotBlank(baseInfo.getCustomerRefDate())) {
            SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = spf.parse(baseInfo.getCustomerRefDate());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            orderSDO.setCustomerExpectDate(date);
        }
        orderSDO.setContactor(baseInfo.getContactor());
        orderSDO.setContactorPhone(baseInfo.getPhone());
        orderSDO.setTransportModeCode(baseInfo.getDeliveryMethod());

        Map<String, OrderLineSDO> orderLineSDOMap = null;
        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
            orderLineSDOMap = orderSDO.getOrderLineSDOS().stream().collect(Collectors.toMap(OrderLineSDO::getId, o -> o));
        }
        Map<String, OrderLineSDO> finalOrderLineSDOMap = orderLineSDOMap;
        List<OrderLineSDO> orderLineSDOS = request.getOrderDetailList().stream().map(orderDetail -> {
            OrderLineSDO orderLineSDO = new OrderLineSDO();
            if (orderDetail.getId() != null) {
                orderLineSDO = finalOrderLineSDOMap.get(orderDetail.getId());
            }
            orderLineSDO.setId(orderDetail.getId());
            ScItemSDO scItemSDO = new ScItemSDO();
            scItemSDO.setScItemId(orderDetail.getGoodsId());
            scItemSDO.setScItemTitle(orderDetail.getGoodsName());
            scItemSDO.setUnitPrice(orderDetail.getUnitPrice() == null ? null : orderDetail.getUnitPrice());
            scItemSDO.setScItemOutCode(orderDetail.getGoodsCode());
            scItemSDO.setCategoryCode(orderDetail.getCategoryCode());
            scItemSDO.setCategoryDesc(orderDetail.getCategoryDesc());
            scItemSDO.setCategoryChildCode(orderDetail.getCategoryChildCode());
            scItemSDO.setCategoryChildDesc(orderDetail.getCategoryChildDesc());
            if (StringUtils.isNotBlank(orderDetail.getQuantity()) && null != scItemSDO.getUnitPrice()) {
                scItemSDO.setQuantity(Integer.parseInt(orderDetail.getQuantity()));
                orderLineSDO.setShouldPayFee(scItemSDO.getUnitPrice() * scItemSDO.getQuantity());
            }

            scItemSDO.setSaleUnit(orderDetail.getSaleUnit());
            scItemSDO.setSaleUnitName(orderDetail.getSaleUnitName());
            orderLineSDO.setRemark(orderDetail.getRemark());
            orderLineSDO.setOrderLineTag(orderDetail.getOrderLineTag());
            scItemSDO.setInventoryUnitCode(orderDetail.getInventoryUnitCode());
            scItemSDO.setInventoryUnitName(orderDetail.getInventoryUnit());

            scItemSDO.setProductationTime(orderDetail.getProductionTime());
            if (StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
                orderLineSDO.setModifierId(employeeGetCurrentLoginResponse.getEmployeeId());
                orderLineSDO.setModifierName(employeeGetCurrentLoginResponse.getEmployeeName());
            }
            if (null != orderDetail.getUnitConvert()) {
                scItemSDO.setUnitConvert(String.valueOf(orderDetail.getUnitConvert()));
            }
            if ("return".equals(orderLineSDO.getOrderLineTag())) {
                orderLineSDO.setReturnCharacter("1");
            }
            orderLineSDO.setScItemSDO(scItemSDO);
            orderLineSDO.setRefuseReasonCode(orderDetail.getRejectReason());
            orderLineSDO.setCumulativeProcessingQuantity(orderDetail.getCumulativeProcessingQuantity());
            orderLineSDO.setCumulativeReceiptQuantity(orderDetail.getCumulativeReceiptQuantity());
            orderLineSDO.setSerialNumber(orderDetail.getLineNum());
            if (StringUtils.isNotBlank(orderDetail.getQuantity()) && StringUtils.isNotBlank(orderDetail.getUnitConvert())) {
                BigDecimal quantity = new BigDecimal(orderDetail.getQuantity());
                BigDecimal unitConvert = new BigDecimal(orderDetail.getUnitConvert());
                BigDecimal basicUnitQty = quantity.divide(unitConvert, 3, BigDecimal.ROUND_DOWN);
                if (MapUtils.isEmpty(orderLineSDO.getFeatures())) {
                    Map<String, String> features = new HashMap<>();
                    features.put(SaleOrderConstants.BASIC_UNIT_QTY, basicUnitQty.toString());
                    //手工单价
                    features.put(SaleOrderConstants.MANUAL_PRICE, orderDetail.getManualPrice());
                    //手工总金额
                    features.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, orderDetail.getManualTotalAmount());
                    orderLineSDO.setFeatures(features);
                } else {
                    orderLineSDO.getFeatures().put(SaleOrderConstants.BASIC_UNIT_QTY, basicUnitQty.toString());
                    //手工单价
                    orderLineSDO.getFeatures().put(SaleOrderConstants.MANUAL_PRICE, orderDetail.getManualPrice());
                    //手工总金额
                    orderLineSDO.getFeatures().put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, orderDetail.getManualTotalAmount());

                }
            }
            orderLineSDO.setGmtModified(new Date());
            return orderLineSDO;
        }).collect(Collectors.toList());
        orderSDO.setOrderLineSDOS(orderLineSDOS);
        orderSDO.setGmtModified(new Date());
        OrderOutCodeAssmeble.assembleOrderLineOutCode(orderSDO);
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> cancelOrder(UpdateOrderRequest request) {
        //获取当前登录人信息
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
        OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
        orderQueryRequest.setId(request.getId());
        OrderQueryResponse query = orderQueryServiceRepository.query(orderQueryRequest);
        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> fag = orderWriteEntity.cancelOrder();

        //记录操作日志
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OperateType.EDIT.getOperateType());
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", OrderOperateType.CANCEL.getDesc());
        map.put("status", OrderStatus.CANCELLED.getDesc());
        if (StringUtils.isNotBlank(orderSDO.getOrderBizId())){
            map.put("bizNo", orderSDO.getOrderBizId());
        }
        if (StringUtils.isNotBlank(orderSDO.getOrderType())) {
            SaleOrderTag saleOrderTag = SaleOrderTag.of(orderSDO.getOrderType());
            if (Objects.nonNull(saleOrderTag)) {
                map.put("orderType", saleOrderTag.getDesc());
            }
        }
        String logInfo = JSON.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        log.asyncMonitorObjectChangeV2(opLogModel);
        return fag;
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> submitSaleOrder(UpdateOrderRequest request) {

        //获取当前登录人信息
        try (RedisLock lock = new RedisLock(CACHE_CODE, "submitSaleOrder:" + request.getId(), 0, 8 * 1000)) {
            if (!lock.lock()) {
                return Result.fail(false, "OTS-04-001-00-15-040", request.getId() + "提交处理中，请勿重复提交！");
            }
            EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
            OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
            orderQueryRequest.setId(request.getId());
            OrderQueryResponse query = orderQueryServiceRepository.query(orderQueryRequest);

            if (StringUtils.isBlank(query.getOrderStatus()) || !(query.getOrderStatus().equals(String.valueOf(OrderStatus.BEFORE_SUBMIT.getCode())) || query.getOrderStatus().equals(String.valueOf(OrderStatus.STAY_PUSH.getCode())))) {
                return Result.fail(false, "OTS-04-001-00-15-041", "当前订单状态已变更,请刷新页面后重试！");
            }

            if (CollectionUtils.isEmpty(query.getOrderDetailList())) {
                return Result.fail("999", "没有子单不允许提交");
            }

            //校验仓库是否禁用
            QueryWarehouseByIdRequest byIdRequest = new QueryWarehouseByIdRequest();
            byIdRequest.setId(query.getShippingWarehouse());
            Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(byIdRequest);
            if (warehouseInfoResult == null || warehouseInfoResult.getResult() == null || warehouseInfoResult.getResult().getStatus() == null) {
                return Result.fail("888", "未查询对应的仓库");
            }
            if (warehouseInfoResult.getResult().getStatus() == 2) {
                return Result.fail("999", "此仓库禁用,不允许提交");
            }
            String orderType = query.getOrderType();
            for (OrderDetailDTO orderDetailDTO : query.getOrderDetailList()) {
                // 校验商品是否 可用
                Boolean aBoolean = checkScItemStatus(orderDetailDTO.getGoodsCode());
                if (aBoolean != null) {
                    if (!aBoolean) {
                        return Result.fail(null, "货品状态异常");
                    }
                } else {
                    return Result.fail(null, "货品状态异常");
                }
                if (!LINE_PRICE_NO_LIMIT.contains(orderType) && StringUtils.isEmpty(orderDetailDTO.getUnitPrice())) {
                    return Result.fail("888", "货品价格为空不允许提交");
                }
                if (!LINE_PRICE_NO_LIMIT.contains(orderType) && !orderDetailDTO.getUnitPrice().matches("^[+]?([0-9]+\\.?)?[0-9]+$")) {
                    return Result.fail("888", "货品价格为负数不允许提交");
                }
            }
            OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
            OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
            Result<Boolean> fag = orderWriteEntity.submit();

            doOperateLog(orderSDO, employeeGetCurrentLoginResponse, OrderOperateType.SUBMIT);
            return fag;
        } catch (Exception e) {
            log.error("销售订单提交异常:", e);
            return Result.fail(false, "OTS-04-001-00-15-042", "销售订单:" + request.getId() + ",提交异常:" + e.getMessage());
        }
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> batchSubmitSaleOrder(BatchSubmitSaleOrderRequest request) {
        if (Objects.isNull(request) || CollectionUtils.isEmpty(request.getIds())) {
            return Result.fail("OTS-04-001-00-15-049", "请求参数不能为空！");
        }
        StringBuilder stringBuilder = new StringBuilder();
        List<TradeMessageSDO> messageSDOS = new ArrayList<>();
        String sequenceNo = customSequenceAccessor.getNextStringSequence("cr_b2b_trade_center", "batchCreateOrderSequence");
        //创建任务
        String taskId = startTask(sequenceNo, MessageTaskTypeEnum.ORDER_BATCH_SUBMIT);
        for (Object idObject : request.getIds()) {
            String idObjectString = JSON.toJSONString(idObject);
            String id = JSON.parseObject(idObjectString).getString("id");
            try (RedisLock lock = new RedisLock(CACHE_CODE, "submitSaleOrder:" + id, 0, 8 * 1000)) {
                if (!lock.lock()) {
                    stringBuilder.append(id).append("提交处理中，请勿重复提交！\n");
                    continue;
                }
                EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
                OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
                orderQueryRequest.setId(id);
                OrderQueryResponse query = orderQueryServiceRepository.query(orderQueryRequest);

                if (StringUtils.isBlank(query.getOrderStatus()) || !(query.getOrderStatus().equals(String.valueOf(OrderStatus.BEFORE_SUBMIT.getCode())) || query.getOrderStatus().equals(String.valueOf(OrderStatus.STAY_PUSH.getCode())))) {
                    stringBuilder.append(id).append("当前订单状态已变更,请刷新页面后重试！\n");
                    continue;
                }

                if (CollectionUtils.isEmpty(query.getOrderDetailList())) {
                    stringBuilder.append(id).append("没有子单不允许提交\n");
                    continue;
                }
                //校验仓库是否禁用
                QueryWarehouseByIdRequest byIdRequest = new QueryWarehouseByIdRequest();
                byIdRequest.setId(query.getShippingWarehouse());
                Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(byIdRequest);
                if (warehouseInfoResult == null || warehouseInfoResult.getResult() == null || warehouseInfoResult.getResult().getStatus() == null) {
                    stringBuilder.append(id).append("未查询对应的仓库\n");
                    continue;
                }
                if (warehouseInfoResult.getResult().getStatus() == 2) {
                    stringBuilder.append(id).append("此仓库禁用,不允许提交\n");
                    continue;
                }
                String orderType = query.getOrderType();
                for (OrderDetailDTO orderDetailDTO : query.getOrderDetailList()) {
                    // 校验商品是否 可用
                    Boolean aBoolean = checkScItemStatus(orderDetailDTO.getGoodsCode());
                    if (aBoolean != null) {
                        if (!aBoolean) {
                            stringBuilder.append(id).append("货品状态异常,货品编码").append(orderDetailDTO.getGoodsCode()).append("\n");
                            break;
                        }
                    } else {
                        stringBuilder.append(id).append("货品状态异常,货品编码").append(orderDetailDTO.getGoodsCode()).append("\n");
                        break;
                    }
                    if (!LINE_PRICE_NO_LIMIT.contains(orderType) && StringUtils.isEmpty(orderDetailDTO.getUnitPrice())) {
                        stringBuilder.append(id).append("货品价格为空不允许提交").append(orderDetailDTO.getGoodsCode()).append("\n");
                        break;
                    }
                    if (!LINE_PRICE_NO_LIMIT.contains(orderType) && !orderDetailDTO.getUnitPrice().matches("^[+]?([0-9]+\\.?)?[0-9]+$")) {
                        stringBuilder.append(id).append("货品价格为负数不允许提交").append(orderDetailDTO.getGoodsCode()).append("\n");
                        break;
                    }
                }
                OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
                OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
                Result<TradeMessageSDO> tradeMessageSDOResult = orderWriteEntity.submitOrderStatusSave();
                if (Objects.isNull(tradeMessageSDOResult.getResult()) || !tradeMessageSDOResult.isSuccess()) {
                    stringBuilder.append(id).append("提交销售订单失败").append(tradeMessageSDOResult.getMessage()).append("\n");
                    continue;
                }
                messageSDOS.add(tradeMessageSDOResult.getResult());
                doOperateLog(orderSDO, employeeGetCurrentLoginResponse, OrderOperateType.SUBMIT);

            } catch (Exception e) {
                log.error("销售订单提交异常:", e);
                stringBuilder.append(id).append("销售订单提交异常").append(e.getMessage());
            }
        }
        if (CollectionUtils.isNotEmpty(messageSDOS)) {
            updateTask(messageSDOS, taskId);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
            Boolean batchSendResp = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleBatchCreated", sequenceNo, sequenceNo, map);
            if (!batchSendResp) {
                log.error("OrderWriteEntity_Batch_submitMQ_fail");
                return Result.fail(Boolean.FALSE, "", "OrderWriteEntity_Batch_submitMQ_fail");
            }
        }
        String errorMessage = stringBuilder.toString();
        if (StringUtils.isNotBlank(errorMessage)) {
            return Result.fail("", errorMessage);
        }
        return Result.success(Boolean.TRUE, "提交成功!");
    }

    private void updateTask(List<TradeMessageSDO> integratedOrderList, String taskId) {
        //生成销售单对象
        Map<String, List<String>> confirmOrderMap = integratedOrderList.stream().map(TradeMessageSDO::getOrderSDO).collect(Collectors.toMap(OrderSDO::getId, p -> p.getOrderLineSDOS().stream().map(OrderLineSDO::getId).collect(Collectors.toList()), (v1, v2) -> v1));
        //生成销售单对象子单总条数
        AtomicInteger orderSizeAtomic = new AtomicInteger(0);
        confirmOrderMap.values().forEach(o -> orderSizeAtomic.getAndAdd(o.size()));

        MessageTask messageTask = new MessageTask();
        messageTask.setTaskId(Long.valueOf(taskId));
        messageTask.setExtraContent(JSON.toJSONString(confirmOrderMap));
        messageTask.setExtraCount(orderSizeAtomic.get());
        messageTask.setGmt_modified(new Date());
        messageTaskService.update(messageTask);
    }

    @NotNull
    private String startTask(String sequenceNo, MessageTaskTypeEnum taskTypeEnum) {
        MessageTask messageTask = new MessageTask();
        messageTask.setBatchNo(sequenceNo);
        messageTask.setStatus(1);
        messageTask.setType(taskTypeEnum.getValue());
        messageTask.setGmt_create(new Date());
        messageTask.setGmt_modified(new Date());
        CreateResponse createResponse = messageTaskService.create(messageTask);
        return createResponse.getId();
    }

    private void doOperateLog(OrderSDO orderSDO, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse, OrderOperateType operateType) {
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(operateType.getCode());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        opLogModel.setOldValue(JSON.toJSONString(orderSDO));
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(employeeGetCurrentLoginResponse)) {
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", operateType.getDesc());
        map.put("bizNo", orderSDO.getOrderBizId());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(orderSDO.getOrderType())){
            SaleOrderTag saleOrderTag = SaleOrderTag.of(orderSDO.getOrderType());
            if (Objects.nonNull(saleOrderTag)){
                map.put("orderType",saleOrderTag.getDesc());
            }
        }
        if (Objects.nonNull(orderSDO.getStatus())){
            OrderStatus orderStatus = OrderStatus.of(orderSDO.getStatus());
            if (Objects.nonNull(orderStatus)){
                map.put("status",orderStatus.getDesc());
            }
        }
        String logInfo = JSON.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        opLogModel.setNewValue(JSON.toJSONString(queryOrderSDO(orderSDO.getId())));
        log.asyncMonitorObjectChangeV2(opLogModel);
    }

    @Override
    public Result<Boolean> sapCallBack(SapCallBackRequest sapCallBackRequest) {
        return sapCallBackV2(sapCallBackRequest);
    }

    public Result<Boolean> sapCallBackV2(SapCallBackRequest sapCallBackRequest) {
        log.info("sapCallBackV2:" + JSON.toJSONString(sapCallBackRequest));
        if (Objects.isNull(sapCallBackRequest) || CollectionUtils.isEmpty(sapCallBackRequest.getData())) {
            throw new FunctionException("OTS-05-001-10-16-028");
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (ModifyOrderRequest request : sapCallBackRequest.getData()) {
            //request去除单引号字符 因为纪元无法识别单引号，导致报错
            if (StringUtils.isNotBlank(request.getMessage())) {
                request.setMessage(request.getMessage().replace("'", ""));
            }
            // sap报文里的订单id转换成内部主键id  sap: 1开头 中间补0  总长度10
            request.setInnerKey(convertTradeOrderId(request.getInnerKey()));
            String lockBackKey = "sapBackSync:" + request.getInnerKey();
            try (SaleRedisLock lockBack = new SaleRedisLock(CACHE_CODE, lockBackKey, TIMEOUT_MSECS, EXPIRE_MSECS / 2, INTERNAL)) {
                log.info("sapCallBackV2入口 加锁 " + lockBackKey + "|时间：" + new Date());
                if (!lockBack.lock()) {
                    log.error("sapCallBackV2入口 锁超时RedisLock获取锁失败:" + lockBackKey);
                    log.error("sapCallBackV2$006_fail");
                    stringBuilder.append(request.getInnerKey()).append(",获取锁失败\n");
                    continue;
                }
                if (request.getSuccess()) {
                    // sap同步成功、外部单号不能为空
                    if (StringUtils.isBlank(request.getOuterKey())) {
                        stringBuilder.append(request.getInnerKey()).append(",外部单号不能为空\n");
                        continue;
                    }
                    String lockKey = SAP_SYNC + request.getOuterKey();
                    OrderQueryResponse query = new OrderQueryResponse();
                    OrderSDO orderSDO = new OrderSDO();
                    try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS * 3, EXPIRE_MSECS, INTERNAL)) {
                        log.info("sapCallBackV2 加锁 " + lockKey + "|时间：" + new Date());
                        if (!lock.lock()) {
                            log.error("sapCallBackV2 RedisLock获取锁失败:" + lockKey);
                            log.error("sapCallBackV2$006_fail");
                            stringBuilder.append(request.getInnerKey()).append(",有部分单据正在参与其它操作，请稍后重试\n");
                            continue;
                        }
                        log.info("ThreadId:" + Thread.currentThread().getId() + "|SaleRedis.key=" + lockKey + "|lock");
                        OrderQueryRequest queryRequest = new OrderQueryRequest();
                        queryRequest.setId(request.getInnerKey());
                        orderSDO = orderQueryServiceRepository.querySingle(queryRequest);
                        log.info("query终极结果:{}",JSON.toJSONString(query));
                        request.setTradeOrderId(orderSDO.getOrderBizId());

                        if (Objects.nonNull(orderSDO.getStatus())) {
                            // 非已推送或待推送状态的销售单不允许推进为待交货
                            if (!checkOrderStatus(orderSDO.getStatus())) {
                                log.info("sapCallBackV2|当前订单:" + request.getInnerKey() + "|状态:" + orderSDO.getStatus() + "|不允许推进");
                                continue;
                            }
                        }
//                        OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
                        log.info("orderSDO参数:{}",JSON.toJSONString(orderSDO));
                        orderSDO.setOuterOrderId(request.getOuterKey());
                        if (orderSDO.getOrderTag().equals("return")) {
                            orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
                            if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                                orderSDO.getOrderLineSDOS().forEach(SetOrderTag::setExchangeOrderLineSDOStatus);
                            }
                        } else if (orderSDO.getOrderTag().equals("exchange")) {
                            orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
                            if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                                orderSDO.getOrderLineSDOS().forEach(SetOrderTag::setExchangeOrderLineSDOStatus);
                            }
                        } else {
                            orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                            if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                                for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                                    log.info("OrderService.sapCallBackV2 orderLineSDO={}", JSON.toJSONString(orderLineSDO));
                                    // 已取消状态不允许推进到待交货
                                    if (!OrderStatus.CANCELLED.getCode().equals(orderLineSDO.getStatus())) {
                                        orderLineSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                                    }
                                }
                            }
                        }


                        Result<Boolean> updateResult = updateSapSyncSaleOrderStatus(orderSDO);
                    } catch (Exception e) {
                        log.error("OrderServiceImpl.sapCallBackNew|sap回调异常:", e);
                        stringBuilder.append(request.getInnerKey()).append(",").append(e.getMessage()).append("\n");
                    }
                    if (OrderCategoryEnum.STOCK.getCode().equals(orderSDO.getOrderCategoryCode())) {
                        handleStockCallBack(orderSDO);

                    } else {
                        // 推送SAP成功时，发送消息通知其他中心
                        if (SetOrderTag.RETURN.equals(orderSDO.getOrderTag())) {
                            if(CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
                                OrderLineSDO orderLineSDO = orderSDO.getOrderLineSDOS().get(0);
                                orderSDO.setReceiveWareHouseCode(orderLineSDO.getShippingWarehouseCode());
                                orderSDO.setReceiveWareHouseOutCode(orderLineSDO.getShippingWarehouseOutCode());
                                orderSDO.setReceiveWareHouseName(orderLineSDO.getShippingWarehouseName());
                                orderSDO.setReceiveFactoryCode(orderLineSDO.getDeliveryFactoryCode());
                                orderSDO.setReceiveStockCode(orderLineSDO.getStockCode());
                            }
                            orderSDO.getOrderLineSDOS().forEach(line -> {
                                String wareHouseCode = line.getShippingWarehouseCode();
                                String wareHouseOutCode = line.getShippingWarehouseOutCode();
                                String wareHouseName = line.getShippingWarehouseName();
                                String deliveryFactoryCode = line.getDeliveryFactoryCode();
                                String deliveryFactoryName = line.getDeliveryFactoryName();
                                String stockCode = line.getStockCode();
                                String stockName = line.getStockName();
                                line.setShippingWarehouseCode(line.getReceiveWarehouseCode());
                                line.setShippingWarehouseOutCode(line.getReceiveWarehouseOutCode());
                                line.setShippingWarehouseName(line.getReceiveWarehouseName());
                                line.setDeliveryFactoryCode(line.getReceiveFactoryCode());
                                line.setDeliveryFactoryName(line.getDeliveryFactoryName());
                                line.setStockCode(line.getReceiveStockCode());
                                line.setStockName(line.getReceiveStockName());
                                line.setReceiveWarehouseCode(wareHouseCode);
                                line.setReceiveWarehouseOutCode(wareHouseOutCode);
                                line.setReceiveWarehouseName(wareHouseName);
                                line.setReceiveFactoryCode(deliveryFactoryCode);
                                line.setReceiveFactoryName(deliveryFactoryName);
                                line.setReceiveStockCode(stockCode);
                                line.setReceiveStockName(stockName);
                            });
                        }
                        sendOrderInfoToOther(Lists.newArrayList(orderSDO));
                    }
                } else {
                    OrderQueryRequest queryRequest = new OrderQueryRequest();
                    queryRequest.setId(request.getInnerKey());
                    OrderSDO orderSDO = orderQueryServiceRepository.querySingle(queryRequest);
                    request.setTradeOrderId(orderSDO.getOrderBizId());
                    if (Objects.nonNull(orderSDO.getStatus())) {
                        if (!OrderStatus.PUSHING.getCode().equals(orderSDO.getStatus())) {
                            continue;
                        }
                    }
//                    OrderSDO orderSDO = SaveOrderConverter.respConverterSDO(query);
                    // sap回调时,若同步sap状态失败,将销售单状态置为待推送,并记录错误信息
                    //外部单号不为空 考虑重复提交，sap返回了false，订单重复创建说明
                    if (StringUtils.isBlank(orderSDO.getOuterOrderId())) {
                        orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                        //子单状态也变更
                        for (OrderLineSDO x : orderSDO.getOrderLineSDOS()) {
                            x.setStatus(OrderStatus.STAY_PUSH.getCode());
                        }
                    } else {
                        continue;
                    }
                    if (MapUtils.isNotEmpty(orderSDO.getFeatures())) {
                        String pushCount = orderSDO.getFeatures().get(SaleOrderConstants.PUSH_COUNT);
                        Integer count = pushCount == null ? 1 : Integer.parseInt(pushCount) + 1;
                        if (OrderCategoryEnum.STOCK.getCode().equals(orderSDO.getOrderCategoryCode())) {
                            orderSDO.getFeatures().put(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS, String.valueOf(Boolean.FALSE));
                        }
                        orderSDO.getFeatures().put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                        orderSDO.getFeatures().put(SaleOrderConstants.PUSH_COUNT, String.valueOf(count));

                    } else {
                        Map<String, String> map = new HashMap<>();
                        if (OrderCategoryEnum.STOCK.getCode().equals(orderSDO.getOrderCategoryCode())) {
                            map.put(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS, String.valueOf(Boolean.FALSE));
                        }
                        map.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                        map.put(SaleOrderConstants.PUSH_COUNT, "1");
                        orderSDO.setFeatures(map);
                    }
                    //features的msg复制到bizFeatures
                    String bizFeatures = orderSDO.getBizFeatures();
                    log.info("sapCallBackV2 sync before bizFeatures = {}", bizFeatures);
                    Map<String, String> bizFeaturesMap = new HashMap<>();
                    if (StringUtils.isNotBlank(bizFeatures)) {
                        bizFeaturesMap = JSON.parseObject(bizFeatures, Map.class);
                    }
                    bizFeaturesMap.put(SaleOrderConstants.EXT_MESSAGE, request.getMessage());
                    log.info("sapCallBackV2 sync after bizFeatures = {}", JSON.toJSONString(bizFeaturesMap));
                    orderSDO.setBizFeatures(JSON.toJSONString(bizFeaturesMap));
                    Result<Boolean> updateResult = updateSapSyncSaleOrderStatus(orderSDO);
                }
            } catch (Throwable e) {
                log.error("OrderServiceImpl.sapCallBackV2_sap回调异常:", e);
                stringBuilder.append(request.getInnerKey()).append(",").append(e.getMessage()).append("\n");
            }
        }

        // 发送kafka消息
        sendOrderInfoToNYK(sapCallBackRequest);

        if (StringUtils.isNotBlank(stringBuilder.toString())) {
            return Result.fail("OTS-04-001-00-15-062", stringBuilder.toString());
        }
        return Result.success(Boolean.TRUE);
    }

    private void handleStockCallBack(OrderSDO orderSDO) {
        if (StringUtils.isBlank(orderSDO.getOrderBizId())) {
            log.info("handleStockCallBack orderSDO={}",JSON.toJSONString(orderSDO));
            return;
        }
        //重新查询一次
        QueryByOrderBizIdsRequest queryByOrderBizIdRequest= new QueryByOrderBizIdsRequest();
        queryByOrderBizIdRequest.setOrderBizIds(Lists.newArrayList(orderSDO.getOrderBizId()));
        //B-b订单
        Result<List<Order>> bizOrderList = orderService.queryByOrderBizIds(queryByOrderBizIdRequest);
        log.info("handleStockCallBack bizOrderList={}",JSON.toJSONString(bizOrderList));
        if(Objects.isNull(bizOrderList) || CollectionUtils.isEmpty(bizOrderList.getResult())){
            log.error("handleStockCallBack not find {}",JSON.toJSONString(queryByOrderBizIdRequest));
            // TODO 考虑查不到的场景怎么处理
            return ;
        }
        Order bizOrder = bizOrderList.getResult().get(0);
        Map<String, String> features = new HashMap<>();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(bizOrder.getFeatures())) {
            features = JSON.parseObject(bizOrder.getFeatures(), Map.class);
        }
        features.put(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS,String.valueOf(Boolean.TRUE));
        //更新features字段
        UpdateFeaturesRequest updateFeaturesRequest =  new UpdateFeaturesRequest();
        updateFeaturesRequest.setFeatures(JSON.toJSONString(features));
        updateFeaturesRequest.setSyncVersion(bizOrder.getSyncVersion());
        updateFeaturesRequest.setId(String.valueOf(bizOrder.getId()));
        try{
            //更新失败需要重试
            log.info("handleStockCallBack#updateFeaturesRequest={}",JSON.toJSONString(updateFeaturesRequest));
            UpdateFeaturesResponse updateFeaturesResponse = orderService.updateFeatures(updateFeaturesRequest);
            log.info("handleStockCallBack#updateFeaturesResponse={}",JSON.toJSONString(updateFeaturesResponse));

            if (Long.valueOf("1").equals(updateFeaturesResponse.getCount())){
                doSendOrderInfoToOther(features,orderSDO);
                return;
            }
            //失败了，增加重试机制
            Result<List<Order>> second = orderService.queryByOrderBizIds(queryByOrderBizIdRequest);
            if(Objects.isNull(second) || CollectionUtils.isEmpty(second.getResult())){
                // TODO 考虑查不到的场景怎么处理
                return;
            }
            //刷新features
            Order secondOrder = second.getResult().get(0);
            Map<String, String> secondFeatures = new HashMap<>();
            if (org.apache.commons.lang3.StringUtils.isNotBlank(secondOrder.getFeatures())) {
                secondFeatures = JSON.parseObject(secondOrder.getFeatures(), Map.class);
            }
            secondFeatures.put(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS,String.valueOf(Boolean.TRUE));
            UpdateFeaturesRequest secondRequest =  new UpdateFeaturesRequest();
            secondRequest.setFeatures(JSON.toJSONString(secondFeatures));
            secondRequest.setSyncVersion(secondOrder.getSyncVersion());
            secondRequest.setId(String.valueOf(secondOrder.getId()));
            log.info("handleStockCallBack#secondRequest={}",JSON.toJSONString(secondRequest));
            UpdateFeaturesResponse secondUpdateFeaturesResponse = orderService.updateFeatures(secondRequest);
            log.info("handleStockCallBack#secondUpdateFeaturesResponse={}",JSON.toJSONString(secondUpdateFeaturesResponse));
            doSendOrderInfoToOther(secondFeatures, orderSDO);


        }catch (Exception e){
            log.error("OrderWriteServiceImpl#handleStockCallBack",e);
        }

    }

    private void doSendOrderInfoToOther(Map<String, String> features, OrderSDO orderSDO) {
        log.info("orderBizId={}，sapCallBackV2 doSendOrderInfoToOther features={}",orderSDO.getOrderBizId(),JSON.toJSONString(features));
        // 当两个结果都有且都成功时，发送sap回调成功消息通知其他中心；
        if (features.containsKey(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS) && SaleOrderConstants.SUCCESS.equals(features.get(SaleOrderConstants.EXT_CALLBACK_IS_SUCCESS))
                && features.containsKey(SaleOrderConstants.GROUP_CALLBACK_IS_SUCCESS) && SaleOrderConstants.SUCCESS.equals(features.get(SaleOrderConstants.GROUP_CALLBACK_IS_SUCCESS))) {
            // 推送SAP成功时，发送消息通知其他中心
            log.info("OrderWriteServiceImpl#doSendOrderInfoToOther");
            sendOrderInfoToOther(Lists.newArrayList(orderSDO));
        }
    }

    private void sendOrderInfoToOther(List<OrderSDO> orderSDOS) {
        // 发送MQ消息通知其他中心
        if (CollectionUtils.isEmpty(orderSDOS)) {
            return;
        }

        CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
        commonAsyncMessageResponse.setEventCode(InnerMessageEventEnum.SALES_ORDER_CREATED_SAP.getValue());
        commonAsyncMessageResponse.setEventName(InnerMessageEventEnum.SALES_ORDER_CREATED_SAP.getLabel());
        commonAsyncMessageResponse.setData(orderSDOS);

        Boolean sendResult = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SalesOrderEvent",
                JSONObject.toJSONString(commonAsyncMessageResponse));
        log.info("SendMsgToSendKafka_MQ_Result,Request={}, Resp={}",
                JSON.toJSONString(commonAsyncMessageResponse), JSON.toJSONString(sendResult));
    }

    private void sendOrderInfoToNYK(SapCallBackRequest sapCallBackRequest) {
        List<String> orderIds = new ArrayList<>();
        Map<String, String> failMsgMap = new HashMap<>();
        for (ModifyOrderRequest request : sapCallBackRequest.getData()) {
            if (!request.getSuccess()) {
                failMsgMap.put(request.getTradeOrderId(), request.getMessage());
            }
            orderIds.add(request.getTradeOrderId());
        }

        QueryByOrderBizIdsRequest request = new QueryByOrderBizIdsRequest();
        request.setOrderBizIds(orderIds);
        List<OrderSDO> orderSDOS = orderQueryServiceRepository.queryByOrderBizIds(request, false);

        // 发送kafka消息要传的内容
        String fromSys = "";
        String businessUnitCode = "";

        List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = new ArrayList<>();
        for (OrderSDO order : orderSDOS) {
            if (!checkOrderCenterTag(order.getFeatures())) {
                // 非订单中心订单不发kafka消息
                return;
            }

            if (StringUtils.isBlank(fromSys)) fromSys = order.getFromSys();
            if (StringUtils.isBlank(businessUnitCode)) businessUnitCode = order.getBusinessUnitOutCode();

            pushOrderInfoList.add(PushOrderInfoToMnSideRequestOrderInfo.builder()
                    .salesOrderNo(order.getOrderBizId())
                    .orderStatus(failMsgMap.containsKey(order.getOrderBizId()) ? SalesOrderPushStatusEnum.FAIL_CREATE.getOrderStatusCode() : SalesOrderPushStatusEnum.SUCCESS_CREATE.getOrderStatusCode())
                    .message(failMsgMap.get(order.getOrderBizId()))
                    .build());
        }
        if (CollectionUtils.isEmpty(pushOrderInfoList)) {
            return;
        }

        CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
        commonAsyncMessageResponse.setEventCode(AsyncMessageEventEnum.SALES_ORDER_CREATE.getValue());
        commonAsyncMessageResponse.setEventName(AsyncMessageEventEnum.SALES_ORDER_CREATE.getLabel());
        commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
        commonAsyncMessageResponse.setFromSys(fromSys);
        commonAsyncMessageResponse.setBusinessUnitCode(businessUnitCode);
        commonAsyncMessageResponse.setData(pushOrderInfoList);

        Boolean sendResult = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleOrderPushMn",
                JSON.toJSONString(commonAsyncMessageResponse));

        log.info("SendMsgToSendKafka_MQ_Result,Request={}, Resp={}",
                JSON.toJSONString(commonAsyncMessageResponse), JSON.toJSONString(sendResult));
    }

    /**
     * 判断是否为订单中心订单
     */
    public boolean checkOrderCenterTag(Map<String, String> features) {
        String os = features.get("os");
        if (StringUtils.isBlank(os) || !TAG_ORDER_CENTER.equals(os)) {
            return false;
        }
        return true;
    }

    private boolean checkOrderStatus(int status) {
        if (OrderStatus.PUSHING.getCode().equals(status) || OrderStatus.STAY_PUSH.getCode().equals(status)
                || OrderStatus.BEFORE_DELIVERY.getCode().equals(status) || OrderStatus.WAIT_HANDLE.getCode().equals(status)
                || OrderStatus.WAIT_RECEIVING.getCode().equals(status)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    private Result<Boolean> updateSapSyncSaleOrderStatus(OrderSDO orderSDO) {
        OrderOutCodeAssmeble.assembleOrderLineOutCode(orderSDO);
        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(orderSDO);
        Result<Boolean> result = orderWriteEntity.modify();

        //记录操作日志
        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("id");
        opLogModel.setOperateType(OrderOperateType.EDIT.getCode());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        map.put("name", "系统");
        map.put("active", OrderOperateType.EDIT.getDesc());
        map.put("bizNo", orderSDO.getOrderBizId());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(orderSDO.getOrderType())){
            SaleOrderTag saleOrderTag = SaleOrderTag.of(orderSDO.getOrderType());
            if (Objects.nonNull(saleOrderTag)){
                map.put("orderType",saleOrderTag.getDesc());
            }
        }
        if (Objects.nonNull(orderSDO.getStatus())){
            OrderStatus orderStatus = OrderStatus.of(orderSDO.getStatus());
            if (Objects.nonNull(orderStatus)){
                map.put("status",orderStatus.getDesc());
            }
        }
        String logInfo = JSON.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
        return result;
    }

    private void extracted(ModifyOrderRequest request, OrderSDO orderSDO, String tag) {
        orderSDO.setOuterOrderId(request.getOutOrderId());
        SetOrderTag.getOrderTag(request.getOrderType(), orderSDO);
        //orderSDO.setOrderTag(SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode().equals(request.getOrderType())?"return":"normal");
        orderSDO.setOrderType(request.getOrderType());
        orderSDO.setOrganizationCode(request.getSaleOrganizationCode());
        orderSDO.setOrganizationName(request.getSaleOrganizationName());
        orderSDO.setChannelCode(request.getSapChannel());
        orderSDO.setChannelName(request.getSapChannelName());
        orderSDO.setProductGroupCode(request.getProductGroupCode());
        orderSDO.setProductGroupName(request.getProductGroupName());
        orderSDO.setCreatorId(request.getCreator());
        orderSDO.setSaleChannelCode(request.getSaleChannelCode());
        orderSDO.setSaleChannelName(request.getSaleChannelName());
        if ("create".equals(tag)) {
            orderSDO.setBisUnitCode(request.getBisUnitCode());
        }
        //更新时不做更新，只有创建时，才赋值
        if (orderSDO.getDepartmentCode() == null) {
            orderSDO.setDepartmentCode(request.getSaleDepartmentCode());
            orderSDO.setDepartmentName(request.getSaleDepartmentName());
        }
        //订单类型判断，无论是更新还是创建均进行识别
        String orderTag = SetOrderTag.getOrderTag(request.getOrderType());
        orderSDO.setOrderTag(orderTag);
        if ("update".equals(tag) && (OrderStatus.STAY_PUSH.getCode().equals(orderSDO.getStatus())
                || OrderStatus.PUSHING.getCode().equals(orderSDO.getStatus()))) {
            SetOrderTag.setOrderSDOStatusOne(orderSDO);
        }
        //设置features字段begin
        Map<String, String> features = orderSDO.getFeatures();
        if (MapUtils.isEmpty(features)) {
            features = new HashMap<>();
            orderSDO.setFeatures(features);
        }
        features.put(SaleOrderConstants.BEGIN_TIME, request.getBeginTime());
        features.put(SaleOrderConstants.PRICE_TIME, request.getPriceTime());
        //设置信贷检查情况
        this.setCreditCheck(features, request.getCreditCheckStatus());
        //处理并发情况下015、006，对B-b的feature字段覆盖
        setGroupCallbackTag(features,orderSDO);
        //同步信贷检查情况到bizFeatures
        String bizFeatures = orderSDO.getBizFeatures();
        Map<String,String> bizFeaturesMap  = new HashMap<>();
        if(StringUtils.isNotBlank(bizFeatures)){
            bizFeaturesMap = JSON.parseObject(bizFeatures, Map.class);
        }
        bizFeaturesMap.put(SaleOrderConstants.CREDIT_MSG,features.get(SaleOrderConstants.CREDIT_CHECK_STATUS_NAME));

        orderSDO.setBizFeatures(JSON.toJSONString(bizFeaturesMap));
        //设置features字段end
        orderSDO.setExt(features.get(SaleOrderConstants.CREDIT_CHECK_CODE));
        orderSDO.setGmtModified(request.getGmtModified() == null ? null : DateFormatUtil.parseSimpleDateFormat(request.getGmtModified()));
        orderSDO.setCustomerExpectDate(request.getExpectedDeliveryTime() == null ? null : DateFormatUtil.parseSimpleDateFormat(request.getExpectedDeliveryTime()));
        orderSDO.setCustomerCode(request.getSoldPartCode());
        orderSDO.setCustomerName(request.getSoldPartName());
        orderSDO.setReceiveAddressCode(request.getDeliveryPartCode());
        orderSDO.setReceiveDetailAddress(request.getDeliveryPartName());
        orderSDO.setTransportModeCode(request.getShipType());
        orderSDO.setRemark(request.getRemark());
        orderSDO.setCustomerReferenceNumber(request.getCustomerReferenceNo());
        orderSDO.setCashCustomerName(request.getCashCustomerName());
        orderSDO.setCostCenter(request.getCostCenter());
        orderSDO.setCreateReason(request.getCreateReason());
        orderSDO.setCustomerAccounts(request.getCustomerAccounts());
        orderSDO.setContactor(request.getContactor());
        orderSDO.setContactorPhone(request.getContactorPhone());
        //key = 子单行号
        Map<String, OrderLineSDO> orderLineMap = Optional.ofNullable(orderSDO.getOrderLineSDOS()).orElse(Lists.newArrayList()).stream().collect(Collectors.toMap(OrderLineSDO::getSerialNumber, o -> o, (k1, k2) -> k1));
        //key = 外部子单行号
        Map<String, OrderLineSDO> outOrderLineMap = Optional.ofNullable(orderSDO.getOrderLineSDOS()).orElse(Lists.newArrayList()).stream().collect(Collectors.toMap(OrderLineSDO::getOuterOrderLineId, o -> o, (k1, k2) -> k1));

        if (CollectionUtils.isNotEmpty(request.getModifyOrderLineRequests())) {
            List<OrderLineSDO> orderLineSDOList = request.getModifyOrderLineRequests().stream().map(modifyOrderLineRequest -> {
                // 如果有已存在子单
                orderSDO.setWareHouseCode(modifyOrderLineRequest.getWarehouseCode());
                orderSDO.setWareHouseName(modifyOrderLineRequest.getWarehouseName());
                //2023.02.27
                //如果是换货订单那么我们应该从换货行取主单 在退货行取收货仓
                if (SaleOrderTag.EXCHANGE_ORDER.getCode().equals(orderSDO.getOrderType())) {
                    //1退货行
                    if (RETURN_FLAG.equals(modifyOrderLineRequest.getReturnFlag())) {
                        //退货行的仓库放到退货仓
                        orderSDO.setReceiveWareHouseCode(modifyOrderLineRequest.getWarehouseCode());
                        orderSDO.setReceiveWareHouseName(modifyOrderLineRequest.getReceiveWareHouseName());
                    } else {
                        //换货行的仓库放到发货仓
                        orderSDO.setWareHouseCode(modifyOrderLineRequest.getWarehouseCode());
                        orderSDO.setWareHouseName(modifyOrderLineRequest.getWarehouseName());
                    }
                }
                OrderLineSDO orderLineSDO = null;

                if (orderLineMap.containsKey(modifyOrderLineRequest.getOrderLineId())) {
                    orderLineSDO = orderLineMap.get(modifyOrderLineRequest.getOrderLineId());
                }
                if(Objects.isNull(orderLineSDO) && orderLineMap.containsKey(modifyOrderLineRequest.getOutOrderLineId())){
                    orderLineSDO = orderLineMap.get(modifyOrderLineRequest.getOutOrderLineId());
                }
                //10  20 20的不存在所以新建了
                if (orderLineSDO == null && outOrderLineMap.containsKey(modifyOrderLineRequest.getOutOrderLineId())) { //10 20
                    orderLineSDO = outOrderLineMap.get(modifyOrderLineRequest.getOutOrderLineId());
                }
                if (orderLineSDO == null) {
                    orderLineSDO = new OrderLineSDO();
                    orderLineSDO.setSerialNumber(modifyOrderLineRequest.getOrderLineId());
                }

                orderLineSDO.setOuterOrderLineId(modifyOrderLineRequest.getOutOrderLineId());
                ScItemSDO scItemSDO = new ScItemSDO();
                scItemSDO.setScItemId(modifyOrderLineRequest.getScItemId());
                scItemSDO.setScItemTitle(modifyOrderLineRequest.getScItemName());
                scItemSDO.setQuantity(Integer.valueOf(modifyOrderLineRequest.getQuantity()));
                scItemSDO.setActivityPrice(modifyOrderLineRequest.getActivityPrice() == null ? null : Long.valueOf(modifyOrderLineRequest.getActivityPrice()));
                scItemSDO.setUnitPrice(modifyOrderLineRequest.getPrice() == null ? null : Long.valueOf(modifyOrderLineRequest.getPrice()));
                scItemSDO.setScItemOutCode(modifyOrderLineRequest.getScItemOutCode());

                scItemSDO.setSaleUnit(modifyOrderLineRequest.getSaleUnit());
                scItemSDO.setSaleUnitName(modifyOrderLineRequest.getSaleUnitName());
                orderLineSDO.setShouldPayFee(modifyOrderLineRequest.getSubTotalAmount() == null ? null : Long.valueOf(modifyOrderLineRequest.getSubTotalAmount()));
                scItemSDO.setInventoryUnitName(modifyOrderLineRequest.getInventoryUnit());
                scItemSDO.setInventoryUnitCode(modifyOrderLineRequest.getInventoryUnitCode());
                scItemSDO.setUnitConvert(modifyOrderLineRequest.getUnitConvert());
                //2022-01-02
                scItemSDO.setCategoryCode(modifyOrderLineRequest.getCategoryCode());
                scItemSDO.setCategoryDesc(modifyOrderLineRequest.getCategoryDesc());
                scItemSDO.setCategoryChildCode(modifyOrderLineRequest.getCategoryChildCode());
                scItemSDO.setCategoryChildDesc(modifyOrderLineRequest.getCategoryChildDesc());
                scItemSDO.setItemBarCode(modifyOrderLineRequest.getProductBarCode());
                scItemSDO.setProductationTime(modifyOrderLineRequest.getProductionTime());
                orderLineSDO.setConfirmQuantity(modifyOrderLineRequest.getConfirmQuantity());
                orderLineSDO.setReturnCharacter(modifyOrderLineRequest.getReturnFlag());
                orderLineSDO.setRefuseReasonCode(modifyOrderLineRequest.getCloseCode());
                orderLineSDO.setRefuseReasonName(modifyOrderLineRequest.getCloseReason());
                orderLineSDO.setStockConversionNum(modifyOrderLineRequest.getStockConversionNum());
                orderLineSDO.setScItemSDO(scItemSDO);
                orderLineSDO.setGmtModified(new Date());
                orderLineSDO.setGiftQuantity(modifyOrderLineRequest.getGiftQuantity());
                orderLineSDO.setTaxRate(modifyOrderLineRequest.getTaxRate());
                // 一盘货新增字段
                if (modifyOrderLineRequest.getActivityPrice() != null && modifyOrderLineRequest.getSubTotalAmount() != null) {
                    orderLineSDO.setTotalActivityFee(modifyOrderLineRequest.getSubTotalAmount());
                }

                //识别子单标签
                if (StringUtils.isNotBlank(orderTag)) {
                    if (SetOrderTag.EXCHANGE.equals(orderTag)) {
                        if ("1".equals(modifyOrderLineRequest.getReturnFlag())) {
                            orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                        } else {
                            orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                        }

                    }
                    if (SetOrderTag.RETURN.equals(orderTag)) {
                        orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                    }
                    if (SetOrderTag.NORMAL.equals(orderTag)) {
                        orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                    }
                }
                if ("update".equals(tag) && (OrderStatus.STAY_PUSH.getCode().equals(orderLineSDO.getStatus())
                        || OrderStatus.PUSHING.getCode().equals(orderLineSDO.getStatus()))) {
                    log.info("OrderService.extracted setOrderLineSDOStatusOne orderLineSDO1={}", JSON.toJSONString(orderLineSDO));
                    SetOrderTag.setOrderLineSDOStatusOne(orderLineSDO);
                    log.info("OrderService.extracted setOrderLineSDOStatusOne orderLineSDO2={}", JSON.toJSONString(orderLineSDO));
                }

                //modify by 皓晖 at 20211217 for 优化扩展字段赋值 begin
                //设置orderLine扩展字段
                this.setOrderLineFeature(modifyOrderLineRequest, orderLineSDO);
                //modify by 皓晖 at 20211217 for 优化扩展字段赋值 end
                if ("create".equals(tag)) {
                    orderLineSDO.setActivityCode(modifyOrderLineRequest.getActivityCode());
                    orderLineSDO.getFeatures().put("activityDteails", modifyOrderLineRequest.getActivityFeature());
                }
                //modify by myw at 20230208 for 销售单明细活动总金额 end
                if (StringUtils.isNotBlank(modifyOrderLineRequest.getActivityPrice()) && BigDecimal.ZERO.compareTo(new BigDecimal(modifyOrderLineRequest.getActivityPrice())) != 0) {
                    long actualPaidFee = new BigDecimal(modifyOrderLineRequest.getActivityPrice()).multiply(new BigDecimal(modifyOrderLineRequest.getQuantity())).longValue();
                    orderLineSDO.setActualPaidFee(actualPaidFee);
                }

                return orderLineSDO;
            }).collect(Collectors.toList());
            orderSDO.setOrderLineSDOS(orderLineSDOList);
            orderSDO.setGmtModified(new Date());
        }
    }

    private void setGroupCallbackTag(Map<String, String> featuresMap, OrderSDO orderSDO) {
        log.info("OrderWriteServiceImpl setGroupCallbackTag orderSDO={}",JSON.toJSONString(orderSDO));
        try{
            String[] orderType = {"ZFD3","ZOR2"};
            List<String> orderTypeList = Arrays.asList(orderType);
            //如果不是F-B-b的B-b就不处理
            if(!(OrderCategoryEnum.STOCK.getCode().equals(orderSDO.getOrderCategoryCode())  && orderTypeList.contains(orderSDO.getOrderType()))){
                return;
            }
            //如果有标记了就不处理
            if(featuresMap.containsKey(SaleOrderConstants.GROUP_CALLBACK_IS_SUCCESS)){
                return;
            }
            if(StringUtils.isEmpty(orderSDO.getRelationNo())){
                return;
            }
            //查询F-B订单的状态
            QueryByOrderBizIdsRequest queryByOrderBizIdRequest= new QueryByOrderBizIdsRequest();
            List<String> list = new ArrayList<>();
            list.add(orderSDO.getRelationNo());
            queryByOrderBizIdRequest.setOrderBizIds(list);
            //B-b订单
            Result<List<Order>> bizOrderList = orderService.queryByOrderBizIds(queryByOrderBizIdRequest);
            log.info("OrderWriteServiceImpl setGroupCallbackTag queryByOrderBizIds ={},bizOrderList={}", JSON.toJSONString(queryByOrderBizIdRequest),JSON.toJSONString(bizOrderList));
            if(Objects.isNull(bizOrderList) || CollectionUtils.isEmpty(bizOrderList.getResult())){
                return ;
            }
            Order order = bizOrderList.getResult().get(0);
            if(Objects.equals(OrderStatus.BEFORE_DELIVERY.getCode(),order.getStatus()) || StringUtils.isNotEmpty(order.getOuterOrderId())){
                featuresMap.put(SaleOrderConstants.GROUP_CALLBACK_IS_SUCCESS,"true");
            }
        }catch (Exception e){
            log.error("OrderWriteServiceImpl setGroupCallbackTag error",e);
        }
    }

    private void setOrderLineFeature(ModifyOrderLineRequest modifyOrderLineRequest, OrderLineSDO orderLineSDO) {
        Map<String, String> orderLineFeatures = orderLineSDO.getFeatures();
        if (null == orderLineFeatures) {
            orderLineFeatures = new HashMap<>();
        }

        Map<String, String> orderLineMap = new HashMap<>();
        if (StringUtils.isNotBlank(modifyOrderLineRequest.getFeatures())) {
            orderLineMap = JSON.parseObject(modifyOrderLineRequest.getFeatures(), Map.class);
        }

        // 判断修改的入参里是否有赠品标识，如果没有则用db里的数据回填，防止015回调的时候把赠品标识清空
        String giftFlag = orderLineFeatures.get("giftFlag");
        giftFlag = StringUtils.isNotBlank(modifyOrderLineRequest.getGiftFlag()) ? modifyOrderLineRequest.getGiftFlag() : giftFlag;

        orderLineMap.put(SaleOrderConstants.GIFT_ACTIVITY_ID, modifyOrderLineRequest.getGiftActivityId());
        orderLineMap.put(SaleOrderConstants.GIFT_PROMOTION_ID, modifyOrderLineRequest.getGiftPromotionId());
        orderLineMap.put(SaleOrderConstants.GIFT_FLAG, giftFlag);
        orderLineMap.put(SaleOrderConstants.SPECIAL_ACTIVITY_ID, modifyOrderLineRequest.getSpecialActivityId());
        orderLineMap.put(SaleOrderConstants.SPECIAL_PROMOTION_ID, modifyOrderLineRequest.getSpecialPromotionId());
        orderLineMap.put(SaleOrderConstants.MANUAL_PROMOTION_ID, modifyOrderLineRequest.getManualPromotionId());
        orderLineMap.put(SaleOrderConstants.TURNING_PRICE, modifyOrderLineRequest.getTurningPrice());
        orderLineMap.put(SaleOrderConstants.DCT_BEFORE_PRICE, modifyOrderLineRequest.getDctBeforePrice());
        orderLineMap.put(SaleOrderConstants.DISCOUNT, modifyOrderLineRequest.getDiscount());
        orderLineMap.put(SaleOrderConstants.NK_PRICE, modifyOrderLineRequest.getNkPrice());
        orderLineMap.put(SaleOrderConstants.SHIP_POINT, modifyOrderLineRequest.getShipPoint());
        orderLineMap.put(SaleOrderConstants.INVENTORY_CODE, modifyOrderLineRequest.getInventoryCode());
        orderLineMap.put(SaleOrderConstants.FACTORY_CODE, modifyOrderLineRequest.getFactoryCode());
        orderLineMap.put(SaleOrderConstants.ACT_OCC_QTY, modifyOrderLineRequest.getActOccQty());
        orderLineMap.put(SaleOrderConstants.ACT_OCC_FEE, modifyOrderLineRequest.getActOccFee());

        if (SetOrderTag.RETURN.equals(orderLineSDO.getOrderLineTag())) {
            String subTotalAmount = modifyOrderLineRequest.getSubTotalAmount();
            String quantity = modifyOrderLineRequest.getQuantity();
            if (StringUtils.isNotBlank(subTotalAmount) && StringUtils.isNotBlank(quantity)) {
                String unitManualPrice = new BigDecimal(subTotalAmount).divide(new BigDecimal(quantity), 0, RoundingMode.HALF_UP).toString();
                orderLineMap.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, subTotalAmount);
                orderLineMap.put(SaleOrderConstants.MANUAL_PRICE, unitManualPrice);
            }
        }
        orderLineFeatures.putAll(orderLineMap);
        orderLineSDO.setFeatures(orderLineFeatures);
    }

    @Override
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> sapDeleteSaleOrder(SapDeleteSaleOrderRequest sapDeleteSaleOrderRequest) {
        log.info("OrderServiceImpl sapDeleteSaleOrder requestParams:" + JSON.toJSONString(sapDeleteSaleOrderRequest));

        if (StringUtils.isBlank(sapDeleteSaleOrderRequest.getOutOrderId())) {
            return Result.fail("OTS-05-001-10-16-053", "sap同步删除销售订单参数不能为空");
        }

        String lockKey = SAP_SYNC + sapDeleteSaleOrderRequest.getOutOrderId();
        try (SaleRedisLock lock = new SaleRedisLock(CACHE_CODE, lockKey, TIMEOUT_MSECS, EXPIRE_MSECS, INTERNAL)) {
            if (!lock.lock()) {
                log.error("sapDeleteSaleOrder未获取到锁|外部单号为:" + lockKey);
                log.error("sapDeleteSaleOrder$019_fail");
                return Result.fail("OTS-04-001-00-16-054", "删除销售单未获取到分布式锁");
            }
            log.info("ThreadId:" + Thread.currentThread().getId() + "|SaleRedis.key=" + lockKey + "|lock");
            OrderPageQueryRequest orderPageQueryRequest = new OrderPageQueryRequest();
            orderPageQueryRequest.setOuterOrderId(sapDeleteSaleOrderRequest.getOutOrderId());
            PageResult<List<OrderPageQueryResponse>> listPageResult = orderQueryServiceRepository.pageQuery(orderPageQueryRequest);
            if (listPageResult == null || CollectionUtils.isEmpty(listPageResult.getContent())) {
                AllocateOrderLoadListRequest allocateOrderLoadListRequest = new AllocateOrderLoadListRequest();
                allocateOrderLoadListRequest.setType(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType());
                allocateOrderLoadListRequest.setOutAllocateOrderId(sapDeleteSaleOrderRequest.getOutOrderId());
                Result<List<AllocateOrder>> allocateOrderListPageResult = allocateOrderService.loadAllocateOrderList(allocateOrderLoadListRequest);
                log.info("关联查询调拨单 结果: {} ", JSON.toJSONString(allocateOrderListPageResult));
                //根据外部单号查询总部销售调拨单为空 报错
                if (allocateOrderListPageResult == null || CollectionUtils.isEmpty(allocateOrderListPageResult.getResult())) {
                    log.error("未查询到订单，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                    return Result.fail("OTS-05-001-10-16-050", "订单id:" + sapDeleteSaleOrderRequest.getOutOrderId() + "未查询到该订单");
                } else {
                    //查询总部销售调拨单子单 统计数量并删除子单
                    AllocateOrder allocateOrder = allocateOrderListPageResult.getResult().get(0);
                    Result<Boolean> booleanResult = deleteAllocateOrder(allocateOrder);
                    if (!booleanResult.getResult()) {
                        log.error("关联删除总部销售调拨单失败 订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                        return Result.fail("OTS-05-001-10-16-051", "sap同步删除销售订单失败,订单ID" + sapDeleteSaleOrderRequest.getOutOrderId());
                    }
                    return Result.success(true);
                }
            }
            OrderPageQueryResponse orderPageQueryResponse = listPageResult.getContent().get(0);
            if (SaleOrderTag.STD_RETURN_ORDER.getDesc().equals(orderPageQueryResponse.getOrderType())) {
                //退货订单 不是待收货状态就报错
                if (OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
                        || OrderStatus.PART_RECEIVING.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                    log.error("该退货订单不是待收货状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                    return Result.fail("OTS-05-001-10-16-045", "该退货订单为非待收货状态无法删除,订单id:" + sapDeleteSaleOrderRequest.getOutOrderId());
                }
            } else if (SaleOrderTag.EXCHANGE_ORDER.getDesc().equals(orderPageQueryResponse.getOrderType())) {
                //换货订单 不是待处理状态就报错
                if (OrderStatus.PARTIAL_HANDLE.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
                        || OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                    log.error("该换货订单不是待处理状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                    return Result.fail("OTS-05-001-10-16-046", "该换货订单为非待处理状态无法删除,订单id:" + sapDeleteSaleOrderRequest.getOutOrderId());
                }
            } else {
                //其他订单不是待交货状态就报错
                if (OrderStatus.PARTIAL_DELIVER.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))
                        || OrderStatus.COMPLETED.getCode().equals(Integer.parseInt(orderPageQueryResponse.getStatusCode()))) {
                    log.error("该销售订单不是待交货状态无法删除，订单号：" + sapDeleteSaleOrderRequest.getOutOrderId());
                    return Result.fail("OTS-05-001-10-16-044", "该销售订单为非待交货状态无法删除,订单id:" + sapDeleteSaleOrderRequest.getOutOrderId());
                }
            }
            OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
            orderQueryRequest.setId(orderPageQueryResponse.getId());
            OrderSDO orderSDO = orderQueryServiceRepository.querySingle(orderQueryRequest);
            List<String> orderLineIds = new ArrayList<>();
            orderSDO.getOrderLineSDOS().forEach(orderLineSDO -> {
                //拒绝原因
                orderLineSDO.setRefuseReasonCode("05");
                orderLineIds.add(orderLineSDO.getId());
            });
            TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
            tradeMessageSDO.setOrderSDO(orderSDO);
            tradeMessageSDO.setAffectLineIds(orderLineIds);
            String message = JSON.toJSONString(tradeMessageSDO);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
            messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleRefused", orderSDO.getOrderBizId(), message, map);
            log.info("order message = " + message);

            OrderWriteEntity orderWriteEntity = OrderWriteFactory.buildOrderEntity(orderSDO);
            orderWriteEntity.deleteOrder();
            return Result.success(true);
        } catch (Exception e) {
            log.error("sapDeleteSaleOrder数据异常:", e);
            return Result.fail("OTS-05-001-10-16-051", "sap同步删除销售订单失败" + e.getMessage());
        }
    }

    public Result<Boolean> deleteAllocateOrder(AllocateOrder allocateOrder) {
        //查询总部销售调拨单子单 循环调拨单子单并且删除子单 最后删除该总部销售调拨单；循环调拨单子单同时根据预报单号和货品id查询对应预报单子单 更新预报字段回复数量/状态 最后更新预报主单
        try {
            AllocateOrderDetailLoadListRequest allocateOrderDetailLoadListRequest = new AllocateOrderDetailLoadListRequest();
            allocateOrderDetailLoadListRequest.setAllocateOrderId(allocateOrder.getId());
            Result<List<AllocateOrderDetail>> allocteOrderDetailResult = allocateOrderDetailService.loadAllocateOrderDetailList(allocateOrderDetailLoadListRequest);
            log.info("019查调拨明细单 结果: {} ", JSON.toJSONString(allocteOrderDetailResult));
            if (allocteOrderDetailResult != null && CollectionUtils.isNotEmpty(allocteOrderDetailResult.getResult())) {
                for (AllocateOrderDetail allocateOrderDetail : allocteOrderDetailResult.getResult()) {
                    Integer quantity = StringConverter.StringToInteger(allocateOrderDetail.getQuantity());
                    //删除调拨单子单
                    DeleteAllocateOrderDetailRequest deleteAllocateOrderDetailRequest = new DeleteAllocateOrderDetailRequest();
                    deleteAllocateOrderDetailRequest.setId(String.valueOf(allocateOrderDetail.getId()));
                    allocateOrderDetailService.deleteAllocateOrderDetail(deleteAllocateOrderDetailRequest);

                    //有的调拨单没有关联预报单就不处理预报单逻辑
                    if (allocateOrder.getAllocateApplyOrderId() != null) {
                        //根据调拨预报单号和货品id查询对应调拨预报单明细  并根据查询预报明细单id更新回复数量和状态
                        AllocateApplyOrderDetailLoadListRequest allocateApplyOrderDetailLoadListRequest = new AllocateApplyOrderDetailLoadListRequest();
                        allocateApplyOrderDetailLoadListRequest.setAllocateApplyOrderId(Integer.valueOf(allocateOrder.getAllocateApplyOrderId()));
                        allocateApplyOrderDetailLoadListRequest.setGoodsId(allocateOrderDetail.getScItemId());
                        Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetailResult = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList(allocateApplyOrderDetailLoadListRequest);
                        log.info("019查调拨预报明细单 参数: {} 结果: {} ", JSON.toJSONString(allocateApplyOrderDetailLoadListRequest), JSON.toJSONString(allocateApplyOrderDetailResult));
                        if (allocateApplyOrderDetailResult != null && CollectionUtils.isNotEmpty(allocateApplyOrderDetailResult.getResult())) {
                            AllocateApplyOrderDetail applyOrderDetail = allocateApplyOrderDetailResult.getResult().get(0);
                            //更新对应的预报单明细单
                            AllocateApplyOrderDetail allocateApplyOrderDetail = new AllocateApplyOrderDetail();
                            allocateApplyOrderDetail.setId(applyOrderDetail.getId());
                            allocateApplyOrderDetail.setReplyQuantity(applyOrderDetail.getReplyQuantity() - quantity);
                            //回复数量回滚至0 状态更新为待回复 反之更新为部分回复
                            if (applyOrderDetail.getReplyQuantity() - quantity <= 0) {
                                allocateApplyOrderDetail.setStatus(AllocateApplyOrderStatusEnum.WAIT_ANSWER.getCode());
                            } else {
                                allocateApplyOrderDetail.setStatus(AllocateApplyOrderStatusEnum.PART_ANSWER.getCode());
                            }
                            allocateApplyOrderDetailService.updateAllocateApplyOrderDetail(allocateApplyOrderDetail);
                        }
                    }
                }
            }

            //有的调拨单没有关联预报单就不处理预报单逻辑
            if (allocateOrder.getAllocateApplyOrderId() != null) {
                //根据总部销售调拨单的预报单单号 查所有的预报单明细 判断其中回复数量 只要其中有回复数量大于0的 这更新预报主单状态为部分回复 反之更新为待回复
                boolean isStatus = false;
                AllocateApplyOrderDetailLoadListRequest allocateApplyOrderDetailLoadListRequest = new AllocateApplyOrderDetailLoadListRequest();
                allocateApplyOrderDetailLoadListRequest.setAllocateApplyOrderId(Integer.valueOf(allocateOrder.getAllocateApplyOrderId()));
                Result<List<AllocateApplyOrderDetail>> allocateApplyOrderDetailResult = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList(allocateApplyOrderDetailLoadListRequest);
                log.info("019查调拨明细单 结果: {} ", JSON.toJSONString(allocateApplyOrderDetailResult));
                if (allocateApplyOrderDetailResult != null && CollectionUtils.isNotEmpty(allocateApplyOrderDetailResult.getResult())) {
                    for (AllocateApplyOrderDetail allocateApplyOrderDetail : allocateApplyOrderDetailResult.getResult()) {
                        //判断子单是否有部分回复状态
                        if (AllocateApplyOrderStatusEnum.PART_ANSWER.getCode().equals(allocateApplyOrderDetail.getStatus())) {
                            isStatus = true;
                            break;
                        }
                    }
                }
                AllocateApplyOrder allocateApplyOrder = new AllocateApplyOrder();
                allocateApplyOrder.setId(Long.valueOf(allocateOrder.getAllocateApplyOrderId()));
                if (isStatus) {
                    allocateApplyOrder.setStatus(AllocateStatusEnum.PART_ANSWER.getCode());
                } else {
                    allocateApplyOrder.setStatus(AllocateStatusEnum.WAIT_ANSWER.getCode());
                }
                allocateApplyOrderService.updateAllocateApplyOrder(allocateApplyOrder);
            }


            //最后删除该总部销售调拨单
            DeleteAllocateOrderRequest deleteAllocateOrderRequest = new DeleteAllocateOrderRequest();
            deleteAllocateOrderRequest.setId(String.valueOf(allocateOrder.getId()));
            allocateOrderService.deleteAllocateOrder(deleteAllocateOrderRequest);
        } catch (Exception e) {
            log.error("019 deleteAllocateOrder error" + e.getMessage());
            return Result.fail(null, e.getMessage());
        }
        log.info("019删除总部销售调拨单及明细单！！！");
        return Result.success(true);
    }

    @Override
    @ProcessInvoker
    public Result<Void> generateOrder(GenerateOrderRequest generateOrderRequest) {
        log.info("OrderServiceImpl generateOrder requestParams:" + JSON.toJSONString(generateOrderRequest));
        if (StringUtils.isEmpty(generateOrderRequest.getOutMaterialCertificateId()) || StringUtils.isEmpty(generateOrderRequest.getAllocateId())) {
            return Result.fail("OTS-05-001-10-16-028", "物料凭证或者调拨单号为空");
        }
        try {
            //此处幂等方案，先将物料凭证放入缓存1天，后续通过es查询是否存在，通过此种方式绕过纪元的模型改动
            boolean lock = epochCacheService.setIfAbsent(SaleOrderConstants.SALE_ORDER_REDIS_CODE, generateOrderRequest.getOutMaterialCertificateId(), "");
            //获取到锁，表明可以新建,获取不到锁，表明是重复请求
            if (!lock) {
                log.info("物料凭证重复:" + generateOrderRequest.getOutMaterialCertificateId());
                return Result.success(null);
            }
            epochCacheService.expire(SaleOrderConstants.SALE_ORDER_REDIS_CODE, generateOrderRequest.getOutMaterialCertificateId(), 30L, TimeUnit.MINUTES);
            //获取到锁 仍然需要校验一下是否已经存在
            PageQueryOrderEsListRequest pageQueryOrderEsListRequest = new PageQueryOrderEsListRequest();
            pageQueryOrderEsListRequest.setMaterialnoList(Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
            Result<List<OrderPageQueryResponse>> resultEs = orderQueryServiceRepository.pageQueryES(pageQueryOrderEsListRequest);
            if (resultEs != null && CollectionUtils.isNotEmpty(resultEs.getResult())) {
                log.info("物料凭证重复:" + generateOrderRequest.getOutMaterialCertificateId());
                return Result.success(null);
            }
            AllocateOrderDetailsQueryRequest request = new AllocateOrderDetailsQueryRequest();
            request.setAllocateOrderId(generateOrderRequest.getAllocateId());
            request.setOutAllocateOrderId(generateOrderRequest.getOuterAllocateId());
            Result<AllocateOrderDetailsQueryResponse> result = allocateOrderReadService.query(request);
            log.info("allocateOrderReadService order response:" + JSON.toJSONString(generateOrderRequest));
            if (!result.isSuccess() || result.getResult() == null) {
                throw new FunctionException("OTS-05-001-10-16-010", "查询调拨单失败");
            }
            AllocateOrderDetailsQueryResponse allocateOrder = result.getResult();
            if (allocateOrder == null) {
                throw new FunctionException("OTS-05-001-10-16-011", "未查询到调拨单");
            }

            OrderSDO orderSDO = new OrderSDO();

            orderSDO.setCustomerCode(allocateOrder.getCustomer());
            orderSDO.setCustomerName(allocateOrder.getCustomerName());
            orderSDO.setOrganizationCode(allocateOrder.getApplyOrgId());
            orderSDO.setOrganizationName(allocateOrder.getApplyOrgName());
            orderSDO.setReceiveAddressCode(allocateOrder.getAddressCode());
            orderSDO.setWareHouseCode(generateOrderRequest.getWareHouseAreaId());

            QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
            queryAddressRequest.setAddressCode(allocateOrder.getBranchCustomersCode());
            queryAddressRequest.setCustomerCode(allocateOrder.getBranchCustomersCode());

            Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
            if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
                throw new FunctionException("OTS-05-001-10-16-014", "未查询到客户收货地址数据");
            }

            CustomerAddressSDO customerAddressSDO = listResult.getResult().get(0);
            if (StringUtils.isBlank(customerAddressSDO.getOrgSaleOrganizationCode())) {
                throw new FunctionException("OTS-05-001-10-16-015", "未查询到客户组织编码");
            }
            orderSDO.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
            orderSDO.setOrganizationName(customerAddressSDO.getOrgSalesOrganizationName());

            QueryGenerateOrderSwitchRequest queryGenerateOrderSwitchRequest = new QueryGenerateOrderSwitchRequest();
            queryGenerateOrderSwitchRequest.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
            queryGenerateOrderSwitchRequest.setStrategyType(StrategyTypeEnum.GENERATE_SWITCH.getCode());
            Result<Boolean> booleanResult = strategyQueryService.queryGenerateOrderSwitch(queryGenerateOrderSwitchRequest);
            if (Objects.isNull(booleanResult) || Objects.isNull(booleanResult.getResult()) || !booleanResult.getResult()) {
                log.error("策略效验返回为false:" + JSON.toJSONString(booleanResult));
                epochCacheService.remove(SaleOrderConstants.SALE_ORDER_REDIS_CODE, Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
                return Result.success(null);
            }
            orderSDO.setReceiveAddressCode(customerAddressSDO.getAddressCode());
            orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddressName());
            orderSDO.setDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode());
            orderSDO.setDepartmentName(customerAddressSDO.getOrgSalesDepartmentName());
            orderSDO.setSaleChannelCode(customerAddressSDO.getOrgSaleChannelCode());
            orderSDO.setSaleChannelName(customerAddressSDO.getOrgSalesChannelName());
            orderSDO.setChannelCode(customerAddressSDO.getChannelCode());
            orderSDO.setChannelName(customerAddressSDO.getChannelName());
            orderSDO.setContactor(customerAddressSDO.getContactName());
            orderSDO.setContactorPhone(customerAddressSDO.getCellphoneNumber());
            orderSDO.setProductGroupCode(allocateOrder.getProductGroup());
            orderSDO.setProductGroupName(allocateOrder.getProductGroupDesc());
            orderSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
            orderSDO.setCustomerName(customerAddressSDO.getCustomerName());
            orderSDO.setSalesmanId(customerAddressSDO.getPrincipal());
            orderSDO.setSalesmanName(customerAddressSDO.getPrincipalName());
            if (allocateOrder.getShipMethod() != null) {
                orderSDO.setTransportModeCode("0" + allocateOrder.getShipMethod());
                orderSDO.setTransportModeName(allocateOrder.getShipMethodDesc());
            }

            orderSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
            orderSDO.setStatusDesc(OrderStatus.BEFORE_DELIVERY.getDesc());
            orderSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());

            orderSDO.setFeatures(new HashMap<String, String>() {{
                if (Objects.nonNull(allocateOrder.getId())) {
                    put(SaleOrderConstants.ALLOCATE_ORDER_ID, String.valueOf(allocateOrder.getId()));
                }
                if (StringUtils.isNotBlank(allocateOrder.getAllocateApplyOrderCode())) {
                    put(SaleOrderConstants.ALLOCATE_ORDER_BIZ_ID, allocateOrder.getAllocateApplyOrderCode());
                }
                if (StringUtils.isNotBlank(allocateOrder.getOutAllocateOrderId())) {
                    put(SaleOrderConstants.STO_SAP_ORDER_ID, allocateOrder.getAllocateApplyOrderId());
                }
                if (Objects.nonNull(generateOrderRequest.getOutMaterialCertificateId())) {
                    put(SaleOrderConstants.MATERIAL_CER_ID, String.valueOf(generateOrderRequest.getOutMaterialCertificateId()));
                }
            }});
            orderSDO.setCreatorId("0");
            orderSDO.setCreatorName("系统");
            orderSDO.setSyncVersion(0);

            //add by 皓晖 at 20211215 for 工厂直发自动生成销售订单时,给sap发送分公司的"创建销售订单014接口报文"缺少发货仓字段 begin
            String wareHouseAreaId = generateOrderRequest.getWareHouseAreaId();
            if (StringUtils.isNotEmpty(wareHouseAreaId)) {
                WarehouseInfo warehouseInfo = this.getWarehouseInfo(wareHouseAreaId);
                if (warehouseInfo != null) {
                    orderSDO.setWareHouseCode(warehouseInfo.getId());
                    orderSDO.setWareHouseName(warehouseInfo.getName());
                }
            }
            //add by 皓晖 at 20211215 for 工厂直发自动成销售订单时,给sap发送分公司的"创建销售订单014接口报文"缺少发货仓字段 end

            orderSDO.setCustomerReferenceNumber(allocateOrder.getSapRefPoNo());
            orderSDO.setCustomerExpectDate(allocateOrder.getExpectedDeliveryDate());
            orderSDO.setCostCenter(allocateOrder.getSapCostCenter());
            orderSDO.setModifierId("0");
            orderSDO.setGmtCreate(new Date());
            orderSDO.setGmtModified(new Date());
            orderSDO.setModifierName("系统");
            orderSDO.setOrderTag("normal");
            orderSDO.setOrderType(SaleOrderTag.STD_ORDER.getCode());
            orderSDO.setOrderTypeName(SaleOrderTag.STD_ORDER.getDesc());


            if (CollectionUtils.isNotEmpty(generateOrderRequest.getScItemList())) {
                List<ScItemDetail> scItemList = generateOrderRequest.getScItemList();

                List<String> scItemIds = scItemList.stream().map(ScItemDetail::getScItemId).collect(Collectors.toList());
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                SearchReqDTO searchReqDTO = new SearchReqDTO();
                searchReqDTO.setScItemIds(scItemIds);
                searchScItemRequest.setSearchReqDTO(searchReqDTO);
                searchScItemRequest.setPageNum(1);
                searchScItemRequest.setPageSize(scItemIds.size());
                Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> scItemListResp = baseDataService.searchScItem(searchScItemRequest);

                Map<String, ForecastOrderLineSDO> hashMap = new HashMap<>();
                if (Objects.nonNull(scItemListResp) && CollectionUtils.isNotEmpty(scItemListResp.getResult())) {
                    hashMap = scItemListResp.getResult().stream().collect(Collectors.toMap(com.epoch.app.bcorder.model.dto.ScItemSDO::getScItemId, t -> {

                        ForecastOrderLineSDO forecastOrderLineSDO = new ForecastOrderLineSDO();
                        forecastOrderLineSDO.setScItemId(t.getScItemId());
                        forecastOrderLineSDO.setScItemTitle(t.getTitle());
                        forecastOrderLineSDO.setScItemOutCode(t.getOuterId());
                        forecastOrderLineSDO.setGoodsCode(t.getOuterId());
                        Map<String, String> features = t.getFeatures();
                        if (MapUtils.isNotEmpty(features)) {
                            String unitName = features.get("unit");
                            String unitCode = features.get("unitName");
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(unitName)) {
                                forecastOrderLineSDO.setInventoryUnit(unitName);
                            }
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(unitCode)) {
                                forecastOrderLineSDO.setInventoryUnitCode(unitCode);
                            }
                        }
                        return forecastOrderLineSDO;
                    }));
                }


                Map<String, ForecastOrderLineSDO> finalHashMap = hashMap;

                List<ForecastOrderLineSDO> lineSDOList = scItemList.stream().map(scItemDetail -> {

                    ForecastOrderLineSDO lineSDO = new ForecastOrderLineSDO();
                    lineSDO = finalHashMap.get(scItemDetail.getScItemId());

                    lineSDO.setQuantity(scItemDetail.getSaleUnitQuantity());
                    lineSDO.setSaleUnitCode(scItemDetail.getSaleUnit());

                    QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemDetail.getScItemId()).build();
                    querySaleUnitRequest.setInventoryUnit(lineSDO.getInventoryUnit());
                    querySaleUnitRequest.setInventoryUnitCode(lineSDO.getInventoryUnitCode());
                    querySaleUnitRequest.setUnitConvert("1");
                    Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                    if (querySaleUnitList.isSuccess() && Objects.nonNull(querySaleUnitList.getResult())) {
                        List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
                        Map<String, SelectCombox> unitMap = new HashMap<>();
                        Nullable.stream(saleUnitListResult).forEach(t -> {
                            unitMap.put(t.getValue(), t);
                        });
                        SelectCombox selected = unitMap.get(lineSDO.getSaleUnitCode());
                        if (selected != null) {
                            lineSDO.setSaleUnit(selected.getLabel());
                            lineSDO.setUnitConvert(selected.getExt());
                        }

                        SelectCombox inventoryMap = unitMap.get(lineSDO.getSaleUnitCode());
                        if (inventoryMap != null) {
                            lineSDO.setInventoryUnit(inventoryMap.getLabel());
                        }
                    }
                    return lineSDO;
                }).collect(Collectors.toList());


                QueryGoodsDetailForMiniprogrameRequest goodsDetail = new QueryGoodsDetailForMiniprogrameRequest();
                goodsDetail.setGoodsList(lineSDOList);
                goodsDetail.setAddressCode(allocateOrder.getBranchCustomersCode());
                QueryGoodsDetailForMiniprogrameResponse goodsDetailResp = crForecastSalesService.queryGoodsDetailForMiniprograme(goodsDetail);

                if (Objects.nonNull(goodsDetailResp) && Objects.nonNull(goodsDetailResp.getResult()) && CollectionUtils.isNotEmpty(goodsDetailResp.getResult().getForecastOrderLineSDOList())) {
                    List<ForecastOrderLineSDO> forecastOrderLineSDO = goodsDetailResp.getResult().getForecastOrderLineSDOList();
                    AtomicInteger count = new AtomicInteger(1);
                    List<OrderLineSDO> orderLineSDOS = forecastOrderLineSDO.stream().map(o -> {
                        OrderLineSDO orderLineSDO = new OrderLineSDO();
                        //行号
                        orderLineSDO.setSerialNumber(String.valueOf(count.get() * 10));
                        count.set(count.get() + 1);
                        ScItemSDO scItemSDO = new ScItemSDO();
                        BeanUtils.copyProperties(o, scItemSDO, "goodsProductationTime");
                        scItemSDO.setScItemId(o.getScItemId());
                        scItemSDO.setScItemTitle(o.getScItemTitle());
                        scItemSDO.setInventoryUnitCode(o.getInventoryUnitCode());
                        scItemSDO.setInventoryUnitName(o.getInventoryUnit());
                        scItemSDO.setSaleUnit(o.getSaleUnitCode());
                        scItemSDO.setSaleUnitName(o.getSaleUnit());
                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroup());
                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroupName());
                        scItemSDO.setScItemOutCode(o.getGoodsCode());
                        scItemSDO.setQuantity(((Number) Double.parseDouble(o.getQuantity())).intValue());
                        if (StringUtils.isNotBlank(o.getExt1()) && ((Number) Double.parseDouble(o.getExt1())).longValue() > 0) {
                            scItemSDO.setUnitPrice(((Number) Double.parseDouble(o.getExt1())).longValue());
                        } else {
                            throw new FunctionException("OTS-05-001-10-16-023", "物料编码:" + o.getScItemId() + ",单价:" + o.getUnitPrice());
                        }

                        scItemSDO.setProductGroupCode(customerAddressSDO.getItemGroup());
                        scItemSDO.setProductGroupName(customerAddressSDO.getItemGroupName());

                        //todo ,if unitPrice or totalFee is null ,zero,negative number,throw new exception
                        orderLineSDO.setScItemSDO(scItemSDO);
                        orderLineSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
                        orderLineSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                        if (StringUtils.isNotBlank(o.getExt2())) {
                            orderLineSDO.setShouldPayFee(((Number) Double.parseDouble(o.getExt2())).longValue());
//                            orderLineSDO.setActualPaidFee(((Number) Double.parseDouble(o.getExt2())).longValue());
                        }
                        orderLineSDO.setCreatorId("0");
                        orderLineSDO.setCreatorName("系统");
                        orderLineSDO.setModifierId("0");
                        orderLineSDO.setModifierName("系统");
                        orderLineSDO.setGmtCreate(new Date());
                        orderLineSDO.setGmtModified(new Date());
                        return orderLineSDO;
                    }).collect(Collectors.toList());

                    orderSDO.setOrderLineSDOS(orderLineSDOS);
                }
            }

            //调拨无需成本中心
            orderSDO.setCostCenter(null);
            SaveSaleOrderRequest saveSaleOrderRequest = new SaveSaleOrderRequest();
            saveSaleOrderRequest.setOrderSDOS(Lists.newArrayList(orderSDO));
            Result resp = this.saveSaleOrder(saveSaleOrderRequest);
        } catch (FunctionException e) {
            e.printStackTrace();
            log.error("生成销售订单异常", e);
            epochCacheService.remove(SaleOrderConstants.SALE_ORDER_REDIS_CODE, Lists.newArrayList(generateOrderRequest.getOutMaterialCertificateId()));
            throw new FacadeException(e);
//            return Result.fail(e.getErrorCode(),e.getMessage());

        }
        return Result.success(null);
    }

    /**
     * 查询逻辑仓信息
     */
    private WarehouseInfo getWarehouseInfo(String wareHouseId) {
        log.info("查询仓库请求信息:" + wareHouseId);
        WarehouseInfo warehouseInfo = null;
        if (StringUtils.isNotEmpty(wareHouseId)) {
            QueryWarehouseByIdRequest request = new QueryWarehouseByIdRequest();
            request.setId(wareHouseId);
            Result<WarehouseInfo> result = unifiedInventoryService.queryWarehouseById(request);
            warehouseInfo = result.getResult();
        }
        log.info("查询仓库返回信息:" + JSON.toJSONString(warehouseInfo));
        return warehouseInfo;
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> rejectOrder(RejectOrderRequest request) {
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
        Boolean aBoolean = orderWriteRepository.rejectOrder(request,employeeGetCurrentLoginResponse);

        return Result.success(aBoolean);
    }

    @Override
    @FacadeInvoker
    public Result<List<ExchangeImportOrderRequest>> excelImportExchangeOrderList(ExcelImportExchangeOrderListRequest exchangeImportRequest) {

        log.info("ExcelImportOrderListRequest  exchangeImportRequest:" + JSON.toJSONString(exchangeImportRequest));
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();

        String sequenceNo = customSequenceAccessor.getNextStringSequence("cr_b2b_trade_center", "batchCreateOrderSequence");
        String taskId = startTask(sequenceNo, MessageTaskTypeEnum.ORDER_BATCH_IMPORT);
        // 获取登陆人 所属组织code
        List<OrganizationSDO> loginOrganizationCodeList = getLoginOrganizationCode(OrganizationTypeEnum.SALES_ORGANIZATION.getCode());
        List<String> loginOrganizationCodes = loginOrganizationCodeList.stream().map(OrganizationSDO::getCode).collect(Collectors.toList());

        // 获取登陆人 业务渠道code
        List<String> organizationIds = loginOrganizationCodeList.stream().map(OrganizationSDO::getId).collect(Collectors.toList());
        List<String> channelCode = businessChannelCodes(organizationIds);

        // 获取登陆人 仓库权限
        List<String> warehouseCodes = getWarehouseCodes();

        Set<String> importAddressCodes = exchangeImportRequest.getImportOrderList().stream()
                .filter(a -> StringUtils.isNotBlank(a.getReceiveAddressCode()))
                .map(ExchangeImportOrderRequest::getReceiveAddressCode)
                .collect(Collectors.toSet());
        // 获取登录人 收货地址权限
        Map<String, List<CustomerAddressSDO>> customerListMap = addressLists(new ArrayList<>(importAddressCodes), employeeGetCurrentLoginResponse);
        List<String> addressCodes = new ArrayList<>(customerListMap.keySet());
        //分子公司经营货品范围校验
        List<ScItemManageRange> scItemManageRanges = searchScItemManageRange();
        //结果数组
        List<ExchangeImportOrderRequest> resultList = new ArrayList<>();
        //异常数组
        List<ExchangeImportOrderRequest> errorList = new ArrayList<>();
        //第一步数据校验的成功的数组
        List<ExchangeImportOrderRequest> successList = new ArrayList<>();
        //库存校验成功的数组
        List<ExchangeImportOrderRequest> checkStockList = new ArrayList<>();
        //去重后子单集合
//        List<ExchangeImportOrderRequest> removeRepeatOrderLineList = new ArrayList<>();
        //创单成功的数组
        List<ExchangeImportOrderRequest> saveSuccessList = new ArrayList<>();

        List<ExchangeImportOrderRequest> importOrderList = exchangeImportRequest.getImportOrderList();

        Map<String, List<ExchangeImportOrderRequest>> check = Nullable.stream(importOrderList).filter(importOrderRequest -> {

            //去空格
            if (StringUtils.isNotBlank(importOrderRequest.getQuantity())) {
                importOrderRequest.setQuantity(importOrderRequest.getQuantity().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getSaleUnit())) {
                importOrderRequest.setSaleUnit(importOrderRequest.getSaleUnit().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getCustomerExpectDate())) {
                importOrderRequest.setCustomerExpectDate(importOrderRequest.getCustomerExpectDate().trim());
            }
            if (StringUtils.isBlank(importOrderRequest.getQuantity())) {
                importOrderRequest.setErrorMessage("订单数量不能为空！");
                errorList.add(importOrderRequest);
                return false;
            }
            int quantityTmp = Integer.parseInt(importOrderRequest.getQuantity());
            if (quantityTmp <= 0 || quantityTmp > 10000000) {
                importOrderRequest.setErrorMessage("订单数量应在0到10000000之间");
                errorList.add(importOrderRequest);
                return false;
            }
            //校验导入订单类型
            if (StringUtils.isNotBlank(importOrderRequest.getOrderType())) {
                boolean flag = importOrderRequest.getOrderType().equals(SaleOrderTag.EXCHANGE_ORDER.getCode());
                if (!flag) {
                    importOrderRequest.setErrorMessage("导入的订单类型不符");
                    errorList.add(importOrderRequest);
                    return false;
                }
            } else {
                importOrderRequest.setErrorMessage("导入的订单类型不能为空");
                errorList.add(importOrderRequest);
                return false;
            }

            //校验业务渠道
            if (StringUtils.isBlank(importOrderRequest.getChannelCode())) {
                importOrderRequest.setErrorMessage("业务渠道不能为空");
                errorList.add(importOrderRequest);
                return false;
            }

            //校验发货仓库
            if (StringUtils.isBlank(importOrderRequest.getShipWareHouseCode())) {
                importOrderRequest.setErrorMessage("发货仓库不能为空");
                errorList.add(importOrderRequest);
                return false;
            }
            //校验收货仓库
            if (StringUtils.isBlank(importOrderRequest.getReceiveWareHouseCode())) {
                importOrderRequest.setErrorMessage("收货仓库不能为空");
                errorList.add(importOrderRequest);
                return false;
            }

            //校验销售组织
            if (StringUtils.isBlank(importOrderRequest.getOrganizationCode())) {
                importOrderRequest.setErrorMessage("销售组织不能为空");
                errorList.add(importOrderRequest);
                return false;
            }


            if (StringUtils.isBlank(importOrderRequest.getCustomerReferenceNo())) {
                importOrderRequest.setErrorMessage("客户参考号不能为空");
                errorList.add(importOrderRequest);
                return false;
            } else {
                importOrderRequest.setCustomerReferenceNo(importOrderRequest.getCustomerReferenceNo().trim());
                if (importOrderRequest.getCustomerReferenceNo().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCustomerReferenceNo()).matches()) {
                    errorList.add(importOrderRequest);
                    importOrderRequest.setErrorMessage("客户参考号不能有特殊字符");
                    return false;
                } else {
                    return true;
                }
            }
        }).collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));

        boolean tag = true;
        String errorMsg = "";

        for (String orderGroupKey : check.keySet()) {
            tag = true;
            errorMsg = "";
            List<ExchangeImportOrderRequest> importOrderRequests = check.get(orderGroupKey);
            //获取到收货仓和发货仓合集 每单底下的明细必须收发货仓分别一致
            List<String> shipWareHouseCodes = importOrderRequests.stream().map(ExchangeImportOrderRequest::getShipWareHouseCode)
                    .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
            List<String> receiveWareHouseCodes = importOrderRequests.stream().map(ExchangeImportOrderRequest::getReceiveWareHouseCode)
                    .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
            //根据客户参考号下的数据遍历
            for (ExchangeImportOrderRequest importOrderRequest : importOrderRequests) {

                // 校验发货仓库信息 填写以填写为准，否则系统根据供货关系默认
                if (StringUtils.isBlank(importOrderRequest.getShipWareHouseCode())) {
                    List<CustomerAddressSDO> customerAddressSDOS = customerListMap.get(importOrderRequest.getReceiveAddressCode());
                    if (!CollectionUtils.isEmpty(customerAddressSDOS)) {
                        CustomerAddressSDO customerAddressSDO = customerAddressSDOS.get(0);
                        // 销售部门 需要 作为入参
                        QueryAllocateRelationForOrderRequest request = QueryAllocateRelationForOrderRequest.builder()
                                .organizationCode(importOrderRequest.getOrganizationCode())
                                .saleChannelCode(customerAddressSDO.getOrgSaleChannelCode())
                                .customerCode(customerAddressSDO.getCustomerCode())
                                .saleDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode()).build();
                        Result<List<AllocateRelationSDO>> listResult = allocateRelationReadService.queryAllocateRelationForOrder(request);
                        if (!ObjectUtils.isEmpty(listResult) && !CollectionUtils.isEmpty(listResult.getResult())) {
                            importOrderRequest.setShipWareHouseCode(listResult.getResult().get(0).getWareHouseCode());
                        }
                    }
                }

                // 校验收货仓库信息 填写以填写为准，否则系统根据供货关系默认
                if (StringUtils.isBlank(importOrderRequest.getReceiveWareHouseCode())) {
                    List<CustomerAddressSDO> customerAddressSDOS = customerListMap.get(importOrderRequest.getReceiveAddressCode());
                    if (!CollectionUtils.isEmpty(customerAddressSDOS)) {
                        CustomerAddressSDO customerAddressSDO = customerAddressSDOS.get(0);
                        // 销售部门 需要 作为入参
                        QueryAllocateRelationForOrderRequest request = QueryAllocateRelationForOrderRequest.builder()
                                .organizationCode(importOrderRequest.getOrganizationCode())
                                .saleChannelCode(customerAddressSDO.getOrgSaleChannelCode())
                                .customerCode(customerAddressSDO.getCustomerCode())
                                .saleDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode()).build();
                        Result<List<AllocateRelationSDO>> listResult = allocateRelationReadService.queryAllocateRelationForOrder(request);
                        if (!ObjectUtils.isEmpty(listResult) && !CollectionUtils.isEmpty(listResult.getResult())) {
                            importOrderRequest.setReceiveWareHouseCode(listResult.getResult().get(0).getWareHouseCode());
                        }
                    }
                }

                //检验客户送达方信息 业务渠道
                List<CustomerAddressSDO> customerAddressSDOS = customerListMap.get(importOrderRequest.getReceiveAddressCode());

                List<CustomerAddressSDO> channelAddressSatisfy = Nullable.stream(customerAddressSDOS).filter(customerAddressSDO ->
                        customerAddressSDO.getChannelCode().equals(importOrderRequest.getChannelCode())
                ).collect(Collectors.toList());

                if (CollectionUtils.isEmpty(channelAddressSatisfy)) {
                    errorMsg = "客户送达方不存在";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }

                if (StringUtils.isNotBlank(importOrderRequest.getCustomerExpectDate())) {
                    if (!DateUtils.isDateFormat(importOrderRequest.getCustomerExpectDate())
                            || Objects.equals("9999-01-01 00:00:00", importOrderRequest.getCustomerExpectDate())) {
                        errorMsg = "期望交货日期格式不正确";
                        tag = false;
                        importOrderRequest.setErrorMessage(errorMsg);
                        break;
                    }
                    Date expectDate = DateUtils.string2Date(importOrderRequest.getCustomerExpectDate());
                    if (Objects.isNull(expectDate)) {
                        errorMsg = "期望交货日期格式不正确";
                        tag = false;
                        importOrderRequest.setErrorMessage(errorMsg);
                        break;
                    }
                    Date firstTime = DateUtils.getFirstTime(new Date());
                    if (expectDate.compareTo(firstTime) < 0) {
                        errorMsg = "期望交货日期不能小于当天";
                        tag = false;
                        importOrderRequest.setErrorMessage(errorMsg);
                        break;
                    }
                } else {
                    errorMsg = "期望交货日期不能为空";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }

                // 校验 导入信息 是否符合登陆人权限
                ImportOrderRequest importCheckTempObject = new ImportOrderRequest();
                BeanUtils.copyProperties(importOrderRequest, importCheckTempObject);
                importCheckTempObject.setWareHouseCode(importOrderRequest.getShipWareHouseCode());
                String errorMessage = importCheckErrorMessage(importCheckTempObject, loginOrganizationCodes, channelCode, warehouseCodes, addressCodes);
                if (StringUtils.isNotBlank(errorMessage)) {
                    errorMsg = errorMessage;
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }

                //校验货品组信息
                if (StringUtils.isNotBlank(importOrderRequest.getProductGroupCode())) {
                    QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                    request.setCode(importOrderRequest.getProductGroupCode());
                    Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                    if (!result.isSuccess() || Objects.isNull(result.getResult()) || Objects.isNull(result.getResult().getCode())) {
                        errorMsg = "货品组信息不存在";
                        tag = false;
                        importOrderRequest.setErrorMessage(errorMsg);
                        break;
                    }
                } else {
                    errorMsg = "货品组信息不能为空";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }
                //校验货品信息
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                SearchReqDTO searchReqDTO = new SearchReqDTO();
                List<String> list = new ArrayList<>();
                list.add(importOrderRequest.getScItecmId());
                searchReqDTO.setOuterIdList(list);
                searchReqDTO.setBusinessType("11");//业态常温
                searchReqDTO.setType(0);//非组合货品
                searchScItemRequest.setSearchReqDTO(searchReqDTO);
                Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
                    errorMsg = "货品信息不存在";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }
                //校验货品范围
                if (CollectionUtils.isNotEmpty(scItemManageRanges)) {
                    //校验货品经营范围
                    String checkMsg = checkScItemManageRange(scItemManageRanges, importOrderRequest.getScItecmId());
                    if (checkMsg != null) {
                        errorMsg = checkMsg;
                        tag = false;
                        importOrderRequest.setErrorMessage(errorMsg);
                        break;
                    }

                }


                if (CollectionUtils.isEmpty(shipWareHouseCodes) || shipWareHouseCodes.size() > 1) {
                    errorMsg = "需生成同一张换货订单的明细行存在发货逻辑仓库不一致数据，请修正后重新导入";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }
                if (CollectionUtils.isEmpty(receiveWareHouseCodes) || receiveWareHouseCodes.size() > 1) {
                    errorMsg = "需生成同一张换货订单的明细行存在收货逻辑仓库不一致数据，请修正后重新导入";
                    tag = false;
                    importOrderRequest.setErrorMessage(errorMsg);
                    break;
                }

            }
            if (tag) {
                successList.addAll(importOrderRequests);
            } else {
                String finalErrorMessage = errorMsg;
                Nullable.stream(importOrderRequests).forEach(it -> {
                    if (StringUtils.isBlank(it.getErrorMessage())) {
                        it.setErrorMessage("同主单下存在校验不通过的子单行");
                    }
                    errorList.add(it);
                });
            }
        }

        //发货仓库存校验逻辑
        if (CollectionUtils.isNotEmpty(successList)) {
            Map<String, List<ExchangeImportOrderRequest>> collect = Nullable.stream(successList).collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));
            for (String orderGroupKey : collect.keySet()) {
                List<ExchangeImportOrderRequest> importOrderRequests = collect.get(orderGroupKey);
                if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                    Set<Boolean> checkInventorySet = Sets.newHashSet();
                    //校验库存
                    for (ExchangeImportOrderRequest importOrderRequest : importOrderRequests) {
                        // 标准销售订单&免费销售订单&现金销售订单创建 校验库存
                        if (SaleOrderTag.EXCHANGE_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
                            ImportOrderRequest excelCheckStockObject = new ImportOrderRequest();
                            BeanUtils.copyProperties(importOrderRequest, excelCheckStockObject);
                            excelCheckStockObject.setWareHouseCode(importOrderRequest.getShipWareHouseCode());
                            ImportOrderRequest excelCheckStockResponse = excelCheckStock(excelCheckStockObject);
                            if (StringUtils.isNotEmpty(excelCheckStockResponse.getErrorMessage())) {
                                errorMsg = excelCheckStockResponse.getErrorMessage();
                                importOrderRequest.setErrorMessage(errorMsg);
                                checkInventorySet.add(false);
                            }
                        }
                    }
                    if (!checkInventorySet.contains(false)) {
                        checkStockList.addAll(importOrderRequests);
                    } else {
                        Nullable.stream(importOrderRequests).forEach(x -> {
                            if (StringUtils.isBlank(x.getErrorMessage())) {
                                x.setErrorMessage("同主单下存在校验不通过的子单行");
                            }
                            errorList.add(x);
                        });
                    }
                }
            }
        }

        //创建销售订单逻辑
        Map<String, List<ExchangeImportOrderRequest>> collect = Nullable.stream(checkStockList).collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));
        List<TradeMessageSDO> tradeMessageSDOS = new ArrayList<>();
        for (String orderGroupKey : collect.keySet()) {
            List<ExchangeImportOrderRequest> importOrderRequests = collect.get(orderGroupKey);
            if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                OrderSDO orderSDO = OrderSDO.builder()
                        .orderType(importOrderRequests.get(0).getOrderType().trim())
                        //标记
                        .remark(importOrderRequests.get(0).getOrderRemark())
                        .createReason(importOrderRequests.get(0).getCreateReason())
                        .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                        .organizationCode(importOrderRequests.get(0).getOrganizationCode())
                        .productGroupCode(importOrderRequests.get(0).getProductGroupCode())
                        .channelCode(importOrderRequests.get(0).getChannelCode())
                        .receiveAddressCode(importOrderRequests.get(0).getReceiveAddressCode())
                        .transportModeCode(importOrderRequests.get(0).getTransportModeCode())
                        .createReason(importOrderRequests.get(0).getCreateReason())
                        .wareHouseCode(importOrderRequests.get(0).getShipWareHouseCode())
                        //2023.02.27 收货仓库
                        .receiveWareHouseCode(importOrderRequests.get(0).getReceiveWareHouseCode())
                        .gmtCreate(new Date())
                        .customerReferenceNumber(importOrderRequests.get(0).getCustomerReferenceNo())
                        .remark(importOrderRequests.get(0).getOrderRemark()).build();
                if (null != importOrderRequests.get(0).getCustomerExpectDate()) {
                    orderSDO.setCustomerExpectDate(DateUtils.string2Date(importOrderRequests.get(0).getCustomerExpectDate()));
                } else {
                    //默认为当前时间后一天
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(new Date());
                    cal.add(Calendar.DAY_OF_MONTH, 1);
                    cal.set(Calendar.HOUR, 0);
                    cal.set(Calendar.MINUTE, 0);
                    cal.set(Calendar.SECOND, 0);
                    cal.set(Calendar.MILLISECOND, 0);
                    orderSDO.setCustomerExpectDate(cal.getTime());
                }

                //查询销售组织信息
                if (StringUtils.isNotBlank(orderSDO.getOrganizationCode())) {
                    GetOrganizationsByOutCodesRequest request = new GetOrganizationsByOutCodesRequest();
                    List<String> list = new ArrayList<>();
                    list.add(orderSDO.getOrganizationCode());
                    request.setOutCodes(list);
                    Result<List<OrganizationSDO>> result = organizationQueryService.getOrganizationsByOutCodes(request);
                    if (Objects.nonNull(result.getResult().get(0))) {
                        OrganizationSDO organizationSDO = result.getResult().get(0);
                        orderSDO.setOrganizationName(organizationSDO.getName());
                        orderSDO.setOrganizationCode(organizationSDO.getCode());
                    }
                }

                //查询业务渠道信息
                if (StringUtils.isNotBlank(orderSDO.getChannelCode())) {
                    QueryChannelRequest baselineBatchQueryChannelsRequest = new QueryChannelRequest();
                    baselineBatchQueryChannelsRequest.setOutCode(orderSDO.getChannelCode());
                    //调用查询渠道信息
                    Result<ChannelResponse> result = channelService.queryChannelDetail(baselineBatchQueryChannelsRequest);
                    orderSDO.setChannelName(result.getResult().getChannelName());
                    orderSDO.setChannelCode(result.getResult().getChannelCode());
                }

                //查询货品组信息
                if (StringUtils.isNotBlank(orderSDO.getProductGroupCode())) {
                    QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                    request.setCode(orderSDO.getProductGroupCode());
                    Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                    orderSDO.setProductGroupName(result.getResult().getName());
                    orderSDO.setProductGroupCode(result.getResult().getCode());
                }

                //查询客户收货地址信息
                if (StringUtils.isNotBlank(orderSDO.getReceiveAddressCode())) {
                    QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
                    queryAddressRequest.setAddressCode(orderSDO.getReceiveAddressCode());
                    queryAddressRequest.setChannelCode(orderSDO.getChannelCode());
                    Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
                    List<CustomerAddressSDO> collect1 = listResult.getResult().stream().filter(customerAddressSDO ->
                            StringUtils.isNotBlank(customerAddressSDO.getPrincipal())
                    ).collect(Collectors.toList());
                    if (Objects.nonNull(collect1.get(0))) {
                        CustomerAddressSDO customerAddressSDO = collect1.get(0);
                        orderSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
                        orderSDO.setCustomerName(customerAddressSDO.getCustomerName());
                        orderSDO.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
                        orderSDO.setOrganizationName(customerAddressSDO.getOrgSalesOrganizationName());
                        orderSDO.setDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode());
                        orderSDO.setDepartmentName(customerAddressSDO.getOrgSalesDepartmentName());
                        orderSDO.setSaleChannelCode(customerAddressSDO.getOrgSaleChannelCode());
                        orderSDO.setSaleChannelName(customerAddressSDO.getOrgSalesChannelName());
                        orderSDO.setChannelCode(customerAddressSDO.getChannelCode());
                        orderSDO.setSalesmanName(customerAddressSDO.getPrincipalName());
                        orderSDO.setChannelName(customerAddressSDO.getChannelName());
                        orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddressName());
                        orderSDO.setReceiveAddressCode(customerAddressSDO.getAddressCode());
                        orderSDO.setAddressCode(customerAddressSDO.getAddressCode());
                        orderSDO.setContactor(customerAddressSDO.getContactName());
                        orderSDO.setContactorPhone(customerAddressSDO.getCellphoneNumber());
                        orderSDO.setBisUnitCode(customerAddressSDO.getOrgBussinessUnitCode());
                        orderSDO.setCreatorId(employeeGetCurrentLoginResponse.getEmployeeId());
                        orderSDO.setCreatorName(employeeGetCurrentLoginResponse.getEmployeeName());
                    }
                }

                //查询客户信息
                if (StringUtils.isNotBlank(orderSDO.getCustomerCode())) {
                    CustomerRequest request = new CustomerRequest();
                    request.setCode(orderSDO.getCustomerCode());
                    Result<CustomerSDO> result = customerQueryService.queryCustomer(request);
                    orderSDO.setCustomerName(result.getResult().getName());
                    orderSDO.setCustomerCode(result.getResult().getCode());
                }
                String factoryCode="";
                String stockCode="";
                //查询逻辑仓信息
                if (StringUtils.isNotBlank(importOrderRequests.get(0).getShipWareHouseCode())) {
                    CargoZoneByOutCodesRequest byIdRequest = new CargoZoneByOutCodesRequest();
                    byIdRequest.setCodes(Arrays.asList(importOrderRequests.get(0).getShipWareHouseCode()));
                    SearchCargoZoneListByOutCodeResponse warehouseInfoResult = unifiedInventoryService.searchCargoZoneListByOutCode(byIdRequest);
                    if(CollectionUtils.isNotEmpty(warehouseInfoResult.getResult())) {
                        WarehouseInfo warehouseInfo = warehouseInfoResult.getResult().get(0);
                        if (Objects.nonNull(warehouseInfo)) {
                            orderSDO.setWareHouseName(warehouseInfo.getName());
                            orderSDO.setWareHouseCode(warehouseInfo.getId());
                            orderSDO.setWareHouseOutCode(warehouseInfo.getCode());
                            factoryCode = warehouseInfo.getSapFactoryCode();
                            stockCode = warehouseInfo.getWarehouseCode();
                        }
                    }
                }
                String receiveFactoryCode="";
                String receiveStockCode="";
                //2023.02.27 查询收货逻辑仓信息
                if (StringUtils.isNotBlank(importOrderRequests.get(0).getReceiveWareHouseCode())) {
                    CargoZoneByOutCodesRequest byIdRequest = new CargoZoneByOutCodesRequest();
                    byIdRequest.setCodes(Arrays.asList(importOrderRequests.get(0).getReceiveWareHouseCode()));
                    SearchCargoZoneListByOutCodeResponse warehouseInfoResult = unifiedInventoryService.searchCargoZoneListByOutCode(byIdRequest);
                    if(CollectionUtils.isNotEmpty(warehouseInfoResult.getResult())) {
                        WarehouseInfo warehouseInfo = warehouseInfoResult.getResult().get(0);
                        if (Objects.nonNull(warehouseInfo)) {
                            orderSDO.setReceiveWareHouseName(warehouseInfo.getName());
                            orderSDO.setReceiveWareHouseCode(warehouseInfo.getId());
                            receiveFactoryCode =warehouseInfo.getSapFactoryCode();
                            receiveStockCode = warehouseInfo.getWarehouseCode();
                        }

                    }
                }

                //设置订单标识
                SetOrderTag.getOrderTag(importOrderRequests.get(0).getOrderType().trim(), orderSDO);
                if(StringUtils.isBlank(orderSDO.getFromSys())) {
                    orderSDO.setFromSys("APP_OTS");
                }
                OrderOutCodeAssmeble.assembleOutCode(orderSDO);
                String id = orderWriteRepository.saveOrder(orderSDO);

                //创建销售明细单
                List<OrderLineSDO> orderLineSDOS = new ArrayList<>();
                int i = 1;
                try {
                    for (ExchangeImportOrderRequest it : importOrderRequests) {
                        OrderLineSDO orderLineSDO = OrderLineSDO.builder()
                                .serialNumber(String.valueOf(i * 10))
                                .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                                .mainOrderBizId(orderSDO.getOrderBizId())
                                .remark(it.getOrderLineRemark())
                                .mainOrderId(id)
                                .shippingWarehouseCode(orderSDO.getWareHouseCode())
                                .shippingWarehouseOutCode(orderSDO.getWareHouseOutCode())
                                .shippingWarehouseName(orderSDO.getWareHouseName())
                                .deliveryFactoryCode(factoryCode)
                                .stockCode(stockCode)
                                .receiveWarehouseCode(orderSDO.getReceiveWareHouseCode())
                                .receiveWarehouseOutCode(orderSDO.getWareHouseOutCode())
                                .receiveWarehouseName(orderSDO.getReceiveWareHouseName())
                                .receiveFactoryCode(receiveFactoryCode)
                                .receiveStockCode(receiveStockCode)
                                .customerCode(orderSDO.getCustomerCode()).build();

                        //识别子单标签
                        orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                        Long unitPrice = null;

                        ScItemSDO scItemSDO = ScItemSDO.builder()
                                .scItemId(it.getScItecmId())
                                .unitPrice(unitPrice)
                                .quantity(Integer.parseInt(it.getQuantity()))
                                .saleUnit(it.getSaleUnit()).build();
                        i++;

                        orderLineSDO.setScItemSDO(scItemSDO);

                        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                        SearchReqDTO searchReqDTO = new SearchReqDTO();
                        List<String> list = new ArrayList<>();
                        list.add(orderLineSDO.getScItemSDO().getScItemId());
                        searchReqDTO.setOuterIdList(list);
                        searchScItemRequest.setSearchReqDTO(searchReqDTO);


                        //查询货品信息
                        Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                        if (listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())) {
                            scItemSDO.setScItemTitle(listResult.getResult().get(0).getTitle());
                            scItemSDO.setScItemId(listResult.getResult().get(0).getScItemId());
                            //                            scItemSDO.setUnit(listResult.getResult().get(0).getUnit());
                        }
                        //库存单位
                        String inventoryUnit = String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName"));
                        QuerySaleOrderLine line = new QuerySaleOrderLine();
                        line.setGoodsId(scItemSDO.getScItemId());
                        line.setGoodsName(scItemSDO.getScItemTitle());
                        line.setQuantity(String.valueOf(scItemSDO.getQuantity()));
                        // 填写以填写为准，否则系统默认库存单位
                        line.setSaleUnit(StringUtils.isBlank(scItemSDO.getSaleUnit()) ? inventoryUnit : scItemSDO.getSaleUnit());

                        line.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                        line.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
                        //                        line.setUnitConvert();
                        QuerySaleOrderLineRequest request = new QuerySaleOrderLineRequest();
                        request.setId(id);
                        request.setSaleOrderLines(Collections.singletonList(line));

                        List<QuerySaleOrderLine> querySaleOrderLines = orderLineQueryServiceRepository.queryScItemInfo(request);

                        // 查询 商品转换关系
                        QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemSDO.getScItemId()).build();
                        querySaleUnitRequest.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                        querySaleUnitRequest.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
                        querySaleUnitRequest.setUnitConvert("1");
                        Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                        List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
                        Map<String, SelectCombox> unitMap = new HashMap<>();
                        Nullable.stream(saleUnitListResult).forEach(t -> {
                            unitMap.put(t.getValue(), t);
                        });

                        SelectCombox selected = new SelectCombox();
                        if (StringUtils.isNotBlank(scItemSDO.getSaleUnit())) {
                            selected = unitMap.get(scItemSDO.getSaleUnit());
                        } else {
                            selected = unitMap.get(inventoryUnit);
                        }

                        if (selected != null) {
                            scItemSDO.setUnitConvert(selected.getExt());
                        }

                        if (CollectionUtils.isNotEmpty(querySaleOrderLines) && null != querySaleOrderLines.get(0)) {
                            scItemSDO.setScItemId(querySaleOrderLines.get(0).getGoodsId());
                            scItemSDO.setScItemTitle(querySaleOrderLines.get(0).getGoodsName());
                            scItemSDO.setScItemOutCode(it.getScItecmId());
                            if (null != querySaleOrderLines.get(0).getUnitConvert()) {
                                scItemSDO.setUnitChangeRelation(String.valueOf(querySaleOrderLines.get(0).getUnitConvert()));
                            }
                            scItemSDO.setInventoryUnitCode(querySaleOrderLines.get(0).getInventoryUnitCode());
                            scItemSDO.setInventoryUnitName(querySaleOrderLines.get(0).getInventoryUnit());
                            if (scItemSDO.getUnitPrice() == null) {
                                scItemSDO.setUnitPrice(querySaleOrderLines.get(0).getUnitPrice() == null ? null : Long.valueOf(querySaleOrderLines.get(0).getUnitPrice()));
                            }


                            scItemSDO.setCategoryCode(querySaleOrderLines.get(0).getCategoryCode());
                            scItemSDO.setCategoryDesc(querySaleOrderLines.get(0).getCategoryDesc());
                            scItemSDO.setCategoryChildCode(querySaleOrderLines.get(0).getCategoryChildCode());
                            scItemSDO.setCategoryChildDesc(querySaleOrderLines.get(0).getCategoryChildDesc());

                            scItemSDO.setFirstCategoryCode(querySaleOrderLines.get(0).getFirstCategoryCode());
                            scItemSDO.setFirstCategoryDesc(querySaleOrderLines.get(0).getFirstCategoryDesc());
                            scItemSDO.setSecondCategoryCode(querySaleOrderLines.get(0).getSecondCategoryCode());
                            scItemSDO.setSecondCategoryDesc(querySaleOrderLines.get(0).getSecondCategoryDesc());


                            orderLineSDO.setScItemSDO(scItemSDO);
                            //创建换货订单换货子订单
                            orderLineWriteRepository.save(orderLineSDO);
                            orderLineSDOS.add(orderLineSDO);
                            //创建换货订单退货子订单

                            orderLineSDO.setSerialNumber(String.valueOf(Integer.parseInt(orderLineSDO.getSerialNumber()) + 1));
                            //识别子单标签
                            orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                            orderLineWriteRepository.save(orderLineSDO);
                            orderLineSDOS.add(orderLineSDO);
                        }
                        saveSuccessList.add(it);
                    }
                } catch (Exception e) {
                    importOrderRequests.stream().forEach(importOrderRequest -> {
                        importOrderRequest.setErrorMessage("创建销售订单失败");
                        errorList.add(importOrderRequest);
                    });
                }

                OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
                orderQueryRequest.setId(id);
                OrderQueryResponse response = orderQueryServiceRepository.query(orderQueryRequest);
                if (Objects.nonNull(response) && StringUtils.isNotBlank(response.getId())) {
                    OrderSDO finalOrderSDO = SaveOrderConverter.respConverterSDO(response);

                    //记录创建操作日志
                    doOperateLog(finalOrderSDO,employeeGetCurrentLoginResponse, OrderOperateType.CREATE );

                    OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(finalOrderSDO);
                    //2022.12.05 记录提交结果
                    //modify by myw,at 20230309,for batch commit sap,end
                    Result<TradeMessageSDO> tradeMessageSDOResult = orderWriteEntity.submitOrderStatusSave();
                    if (Objects.nonNull(tradeMessageSDOResult.getResult()) && tradeMessageSDOResult.isSuccess() && Objects.nonNull(tradeMessageSDOResult.getResult())) {
                        tradeMessageSDOS.add(tradeMessageSDOResult.getResult());
                    }
                    log.info("import_submit_result:{}", JSON.toJSONString(tradeMessageSDOResult));

                    //记录提交操作日志
                    doOperateLog(finalOrderSDO, employeeGetCurrentLoginResponse, OrderOperateType.SUBMIT);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(tradeMessageSDOS)) {
            updateTask(tradeMessageSDOS, taskId);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());

            Boolean batchSendResp = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleBatchCreated", sequenceNo, sequenceNo, map);
            if (!batchSendResp) {
                log.error("OrderWriteEntity_Batch_submitMQ_fail", JSON.toJSONString(tradeMessageSDOS));
//                    return Result.fail(Boolean.FALSE,"","OrderWriteEntity_Batch_submitMQ_fail");
            }
        }
        //失败的条数
        Nullable.stream(errorList).forEach(resultList::add);

        //成功的条数
        Nullable.stream(saveSuccessList).forEach(resultList::add);

        Map<String, String> errorMessageMap = new HashMap<>();
        resultList.stream().forEach(req -> errorMessageMap.put(req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo(), req.getErrorMessage()));
        List<String> errCustomerReferenceNo = importOrderList.stream().filter(x -> StringUtils.isNotBlank(x.getErrorMessage()))
                .map(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()).collect(Collectors.toList());
        log.info("exchangeOrderImport_errCustomerReferenceNo:{}", JSON.toJSONString(errCustomerReferenceNo));
        // 按照导入 原顺序排序
        resultList = Nullable.stream(importOrderList).map(req -> {
            if (CollectionUtils.isNotEmpty(errCustomerReferenceNo) && StringUtils.isBlank(req.getErrorMessage())
                    && errCustomerReferenceNo.contains(req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo())) {
                req.setErrorMessage("同主单的其他销售单行报错");
            }
            return req;
        }).collect(Collectors.toList());

        return Result.success(resultList);
    }

    @Override
    @FacadeInvoker
    public Result<List<ImportOrderRequest>> excelImportOrderList(ExcelImportOrderListRequest excelImportOrderListRequest) {

        log.info("ExcelImportOrderListRequest  excelImportOrderListRequest:" + JSON.toJSONString(excelImportOrderListRequest));
//        String sequenceNo="BSA"+new Date().getTime();
        String sequenceNo = customSequenceAccessor.getNextStringSequence("cr_b2b_trade_center", "batchCreateOrderSequence");
        String taskId = startTask(sequenceNo, MessageTaskTypeEnum.ORDER_BATCH_IMPORT);
        //获取当前登录人
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();

        // 获取登陆人 所属组织code
        List<OrganizationSDO> loginOrganizationCodeList = getLoginOrganizationCode(OrganizationTypeEnum.SALES_ORGANIZATION.getCode());
        List<String> loginOrganizationCodes = loginOrganizationCodeList.stream().map(OrganizationSDO::getCode).collect(Collectors.toList());
        Map<String, String> organizationOutInnerCodeMap = loginOrganizationCodeList.stream().collect(Collectors.toMap(OrganizationSDO::getOutCode, OrganizationSDO::getId, (a, b) -> b));

        // 获取登陆人 业务渠道code
        List<String> organizationIds = loginOrganizationCodeList.stream().map(OrganizationSDO::getId).collect(Collectors.toList());
        List<String> channelCode = businessChannelCodes(organizationIds);

        // 获取登陆人 仓库权限
        List<String> warehouseCodes = getWarehouseCodes();

        Set<String> importAddressCodes = excelImportOrderListRequest.getImportOrderList().stream()
                .map(ImportOrderRequest::getReceiveAddressCode)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toSet());
        // 获取登录人 收货地址权限
        Map<String, List<CustomerAddressSDO>> customerListMap = addressLists(new ArrayList<>(importAddressCodes), employeeGetCurrentLoginResponse);
        // 获取登陆人 收获地址(按送达方编码+销售组织分组),add by myw,for suit fleeing goods use same
        Map<String, List<CustomerAddressSDO>> customerUnitKeyMap = addressUniKeyLists(new ArrayList<>(importAddressCodes), employeeGetCurrentLoginResponse);
        List<String> addressCodes = new ArrayList<>(customerListMap.keySet());
        //获取货品经营范围
        List<ScItemManageRange> scItemManageRanges = searchScItemManageRange();
        //结果数组
        List<ImportOrderRequest> resultList = new ArrayList<>();
        //异常数组
        List<ImportOrderRequest> errorList = new ArrayList<>();
        //第一步数据校验的成功的数组
        List<ImportOrderRequest> successList = new ArrayList<>();
        //库存校验成功的数组
        List<ImportOrderRequest> checkStockList = new ArrayList<>();
        //去重后子单集合 新增需求取消销售单重复限制 modify by myw
//        List<ImportOrderRequest> removeRepeatOrderLineList = new ArrayList<>();
        //创单成功的数组
        List<ImportOrderRequest> saveSuccessList = new ArrayList<>();

        //excel数据处理
        List<ImportOrderRequest> importOrderList = Nullable.stream(excelImportOrderListRequest.getImportOrderList()).map(importOrderRequest -> {
            //去空格
            if (StringUtils.isNotBlank(importOrderRequest.getUnitPrice())) {
                importOrderRequest.setUnitPrice(importOrderRequest.getUnitPrice().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getQuantity())) {
                importOrderRequest.setQuantity(importOrderRequest.getQuantity().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getTotalAmount())) {
                importOrderRequest.setTotalAmount(importOrderRequest.getTotalAmount().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getSaleUnit())) {
                importOrderRequest.setSaleUnit(importOrderRequest.getSaleUnit().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getCustomerExpectDate())) {
                importOrderRequest.setCustomerExpectDate(importOrderRequest.getCustomerExpectDate().trim());
            }
            if (StringUtils.isNotBlank(importOrderRequest.getCreateReason())) {
                importOrderRequest.setCreateReason(importOrderRequest.getCreateReason());
            }
            return importOrderRequest;
        }).collect(Collectors.toList());

        //excel数据校验，检验不通过就加入错误信息然后返回，当前只有销售订单导入前置校验
        List<ImportOrderRequest> checkList = SetOrderTag.RETURN.equals(excelImportOrderListRequest.getOrderTag()) ? importOrderList : Nullable.stream(importOrderList).filter(importOrderRequest -> {
            Boolean checkResult = checkExcelData(importOrderRequest, excelImportOrderListRequest, loginOrganizationCodes);
            if (!checkResult) {
                errorList.add(importOrderRequest);
            }
            return checkResult;
        }).collect(Collectors.toList());

        Map<String, List<ImportOrderRequest>> importOrderGroupMap = checkList.stream().collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));

        String errorMsg = "";
        List<Boolean> tags = Lists.newArrayList();
        for (String orderGroupKey : importOrderGroupMap.keySet()) {
            errorMsg = "";
            //以客户参考号分组 的初步校验成功数据
            //modify by myw,销售订单导入分组条件修改为 req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()
            List<ImportOrderRequest> importOrderRequests = importOrderGroupMap.get(orderGroupKey);
            //根据客户参考号下的数据遍历
            for (ImportOrderRequest importOrderRequest : importOrderRequests) {

                //excel数据校验，针对退货订单导入检验，支持子单明细行检验失败后不生成主单
                if (SetOrderTag.RETURN.equals(excelImportOrderListRequest.getOrderTag()) && !checkExcelData(importOrderRequest, excelImportOrderListRequest, loginOrganizationCodes)) {
                    errorMsg = importOrderRequest.getErrorMessage();
                    tags.add(false);
                    importOrderRequest.setErrorMessage(importOrderRequest.getErrorMessage());
                    continue;
                }

                // 校验仓库信息 默认以填写为准，否则系统根据供货关系填写
                if (StringUtils.isBlank(importOrderRequest.getWareHouseCode())) {
                    String innerOrgId = organizationOutInnerCodeMap.getOrDefault(importOrderRequest.getOrganizationCode(), "");
                    List<CustomerAddressSDO> customerAddressSDOS = customerUnitKeyMap.get(importOrderRequest.getReceiveAddressCode() + "-" + innerOrgId);
                    if (!CollectionUtils.isEmpty(customerAddressSDOS)) {
                        CustomerAddressSDO customerAddressSDO = customerAddressSDOS.get(0);
                        // 销售部门 需要 作为入参
                        QueryAllocateRelationForOrderRequest request = QueryAllocateRelationForOrderRequest.builder()
                                .organizationCode(importOrderRequest.getOrganizationCode())
                                .saleChannelCode(customerAddressSDO.getOrgSaleChannelCode())
                                .customerCode(customerAddressSDO.getCustomerCode())
                                .saleDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode()).build();
                        Result<List<AllocateRelationSDO>> listResult = allocateRelationReadService.queryAllocateRelationForOrder(request);
                        if (!ObjectUtils.isEmpty(listResult) && !CollectionUtils.isEmpty(listResult.getResult())) {
                            importOrderRequest.setWareHouseCode(listResult.getResult().get(0).getWareHouseCode());
                        }
                    }
                }

                // 校验 导入信息 是否符合登陆人权限
                String errorMessage = importCheckErrorMessage(importOrderRequest, loginOrganizationCodes, channelCode, warehouseCodes, addressCodes);
                if (StringUtils.isNotBlank(errorMessage)) {
                    errorMsg = errorMessage;
                    tags.add(false);
                    importOrderRequest.setErrorMessage(errorMessage);
                    continue;
                }

                //校验货品组信息
                if (StringUtils.isNotBlank(importOrderRequest.getProductGroupCode())) {
                    QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                    request.setCode(importOrderRequest.getProductGroupCode());
                    Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                    if (!result.isSuccess() || Objects.isNull(result.getResult()) || Objects.isNull(result.getResult().getCode())) {
                        errorMsg = "货品组信息不存在"; //变量名 改动
                        tags.add(false);
                        importOrderRequest.setErrorMessage(errorMsg);
                        continue;
                    }
                } else {
                    errorMsg = "货品组信息不能为空";
                    tags.add(false);
                    importOrderRequest.setErrorMessage(errorMsg);
                    continue;
                }
                //校验货品信息
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                SearchReqDTO searchReqDTO = new SearchReqDTO();
                List<String> list = new ArrayList<>();
                list.add(importOrderRequest.getScItecmId());
                searchReqDTO.setOuterIdList(list);
                searchReqDTO.setBusinessType("11");//业态常温
                searchReqDTO.setType(0);//非组合货品
                searchScItemRequest.setSearchReqDTO(searchReqDTO);
                Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                if (!listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
                    errorMsg = importOrderRequest.getScItecmId() + "货品信息不存在";
                    tags.add(false);
                    importOrderRequest.setErrorMessage(errorMsg);
                    continue;
                }
                //校验货品经营范围
                if (CollectionUtils.isNotEmpty(scItemManageRanges)) {
                    //校验货品范围
                    String checkMsg = checkScItemManageRange(scItemManageRanges, importOrderRequest.getScItecmId());
                    if (checkMsg != null) {
                        errorMsg = checkMsg;
                        tags.add(false);
                        importOrderRequest.setErrorMessage(errorMsg);
                        continue;
                    }
                }

                //退货订单导入  校验货品单位
                if (SetOrderTag.RETURN.equals(excelImportOrderListRequest.getOrderTag()) && !checkScItemUnit(importOrderRequest, listResult)) {
                    errorMsg = importOrderRequest.getErrorMessage();
                    tags.add(false);
                    importOrderRequest.setErrorMessage(importOrderRequest.getErrorMessage());
                    continue;
                }
            }
            if (!tags.contains(false)) {
                successList.addAll(importOrderRequests);
                tags.clear();
            } else {
                Nullable.stream(importOrderRequests).forEach(it -> {
                    if (StringUtils.isBlank(it.getErrorMessage())) {
                        it.setErrorMessage("同主单下存在校验不通过的子单行");
                    }
                    errorList.add(it);
                });
                tags.clear();
            }
        }

        //库存校验逻辑
        if (CollectionUtils.isNotEmpty(successList)) {
            Map<String, List<ImportOrderRequest>> collect = Nullable.stream(successList).collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));
            for (String key : collect.keySet()) {
                List<ImportOrderRequest> importOrderRequests = collect.get(key);
                if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                    boolean fag = true;
                    //校验库存 todo 优化建议:同主单下面，可以批量查询货品和库存
                    for (ImportOrderRequest importOrderRequest : importOrderRequests) {
                        // 标准销售订单&免费销售订单&现金销售订单创建 校验库存
                        if (SaleOrderTag.STD_ORDER.getCode().equals(importOrderRequest.getOrderType())
                                || SaleOrderTag.FREE_ORDER.getCode().equals(importOrderRequest.getOrderType())
                                || SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
                            ImportOrderRequest importOrderRequestStockCheck = excelCheckStock(importOrderRequest);
                            if (StringUtils.isNotEmpty(importOrderRequestStockCheck.getErrorMessage())) {
                                errorMsg = importOrderRequestStockCheck.getErrorMessage();
                                fag = false;
                                break;
                            }
                        }
                    }
                    if (fag) {
                        checkStockList.addAll(importOrderRequests);
                    } else {
                        String finalErrorMessage = errorMsg;
                        Nullable.stream(importOrderRequests).forEach(x -> {
                            x.setErrorMessage(finalErrorMessage);
                            errorList.add(x);
                        });
                    }
                }
            }
        }

        //创建销售订单逻辑
        if (CollectionUtils.isNotEmpty(checkStockList)) {
            Map<String, List<ImportOrderRequest>> collect = Nullable.stream(checkStockList).collect(Collectors.groupingBy(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()));
            List<TradeMessageSDO> tradeMessageSDOS = new ArrayList<>();
            for (String orderGroupKey : collect.keySet()) {
                List<ImportOrderRequest> importOrderRequests = collect.get(orderGroupKey);
                if (CollectionUtils.isNotEmpty(importOrderRequests) && Objects.nonNull(importOrderRequests.get(0))) {
                    OrderSDO orderSDO = OrderSDO.builder()
                            .orderType(importOrderRequests.get(0).getOrderType().trim())
                            //标记
                            .remark(importOrderRequests.get(0).getOrderRemark())
                            .createReason(importOrderRequests.get(0).getCreateReason())
                            .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                            .organizationCode(importOrderRequests.get(0).getOrganizationCode())
                            .productGroupCode(importOrderRequests.get(0).getProductGroupCode())
                            .channelCode(importOrderRequests.get(0).getChannelCode())
                            .receiveAddressCode(importOrderRequests.get(0).getReceiveAddressCode())
                            .transportModeCode(importOrderRequests.get(0).getTransportModeCode())
                            .createReason(importOrderRequests.get(0).getCreateReason())
                            .wareHouseCode(importOrderRequests.get(0).getWareHouseCode())
                            .costCenter(importOrderRequests.get(0).getCostCenter())
                            .gmtCreate(new Date())
                            .customerReferenceNumber(importOrderRequests.get(0).getCustomerReferenceNo())
                            .remark(importOrderRequests.get(0).getOrderRemark()).build();
                    if (null != importOrderRequests.get(0).getCustomerExpectDate()) {
                        orderSDO.setCustomerExpectDate(TimeUtil.parseYYYY_MM_dd(importOrderRequests.get(0).getCustomerExpectDate()));
                    } else {
                        //默认为当前时间后一天
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(new Date());
                        cal.add(Calendar.DAY_OF_MONTH, 1);
                        orderSDO.setCustomerExpectDate(cal.getTime());
                    }

                    //查询销售组织信息
                    String orgId = null;
                    if (StringUtils.isNotBlank(orderSDO.getOrganizationCode())) {
                        GetOrganizationsByOutCodesRequest request = new GetOrganizationsByOutCodesRequest();
                        List<String> list = new ArrayList<>();
                        list.add(orderSDO.getOrganizationCode());
                        request.setOutCodes(list);
                        Result<List<OrganizationSDO>> result = organizationQueryService.getOrganizationsByOutCodes(request);
                        if (Objects.nonNull(result.getResult().get(0))) {
                            OrganizationSDO organizationSDO = result.getResult().get(0);
                            orderSDO.setOrganizationName(organizationSDO.getName());
                            orderSDO.setOrganizationCode(organizationSDO.getCode());
                            orgId = organizationSDO.getId();
                        }
                    }

                    //查询业务渠道信息
                    if (StringUtils.isNotBlank(orderSDO.getChannelCode())) {
                        QueryChannelRequest baselineBatchQueryChannelsRequest = new QueryChannelRequest();
                        baselineBatchQueryChannelsRequest.setOutCode(orderSDO.getChannelCode());
                        //调用查询渠道信息
                        Result<ChannelResponse> result = channelService.queryChannelDetail(baselineBatchQueryChannelsRequest);
                        orderSDO.setChannelName(result.getResult().getChannelName());
                        orderSDO.setChannelCode(result.getResult().getChannelCode());
                    }

                    //查询货品组信息
                    if (StringUtils.isNotBlank(orderSDO.getProductGroupCode())) {
                        QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                        request.setCode(orderSDO.getProductGroupCode());
                        Result<ScItemGroupResponse> result = scItemGroupQueryService.getScItemGroup(request);
                        orderSDO.setProductGroupName(result.getResult().getName());
                        orderSDO.setProductGroupCode(result.getResult().getCode());
                        orderSDO.setBusinessType(Integer.parseInt(result.getResult().getCode()));
                    }

                    String customerAddressOrgId = null;
                    //查询客户收货地址信息
                    if (StringUtils.isNotBlank(orderSDO.getReceiveAddressCode())) {
                        QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
                        queryAddressRequest.setAddressCode(orderSDO.getReceiveAddressCode());
                        queryAddressRequest.setChannelCode(orderSDO.getChannelCode());
                        queryAddressRequest.setOrgSaleOrganizationCode(orgId);
                        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
                        List<CustomerAddressSDO> collect1 = Nullable.stream(listResult.getResult()).filter(customerAddressSDO ->
                                StringUtils.isNotBlank(customerAddressSDO.getPrincipal())
                        ).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(collect1) && Objects.nonNull(collect1.get(0))) {
                            CustomerAddressSDO customerAddressSDO = collect1.get(0);
                            orderSDO.setCustomerCode(customerAddressSDO.getCustomerCode());
                            orderSDO.setCustomerName(customerAddressSDO.getCustomerName());
                            orderSDO.setOrganizationCode(customerAddressSDO.getOrgSaleOrganizationCode());
                            orderSDO.setOrganizationName(customerAddressSDO.getOrgSalesOrganizationName());
                            orderSDO.setDepartmentCode(customerAddressSDO.getOrgSaleDepartmentCode());
                            orderSDO.setDepartmentName(customerAddressSDO.getOrgSalesDepartmentName());
                            orderSDO.setSaleChannelCode(customerAddressSDO.getOrgSaleChannelCode());
                            orderSDO.setSaleChannelName(customerAddressSDO.getOrgSalesChannelName());
                            orderSDO.setChannelCode(customerAddressSDO.getChannelCode());
                            orderSDO.setSalesmanName(customerAddressSDO.getPrincipalName());
                            orderSDO.setChannelName(customerAddressSDO.getChannelName());
                            orderSDO.setReceiveDetailAddress(customerAddressSDO.getAddressName());
                            orderSDO.setReceiveAddressCode(customerAddressSDO.getAddressCode());
                            orderSDO.setAddressCode(customerAddressSDO.getAddressCode());
                            orderSDO.setContactor(customerAddressSDO.getContactName());
                            orderSDO.setContactorPhone(customerAddressSDO.getCellphoneNumber());
                            orderSDO.setBisUnitCode(customerAddressSDO.getOrgBussinessUnitCode());
                            // 创建人
                            orderSDO.setCreatorId(employeeGetCurrentLoginResponse.getEmployeeId());
                            orderSDO.setCreatorName(employeeGetCurrentLoginResponse.getEmployeeName());
                            customerAddressOrgId = customerAddressSDO.getOrgSaleOrganizationCode();
                        }

                    }
                    //销售组织 和客户收货地址送达方的销售组织不一致
                    if (!Objects.equals(orgId, customerAddressOrgId)) {
                        for (ImportOrderRequest importOrderRequest : importOrderRequests) {
                            importOrderRequest.setErrorMessage("销售组织和客户收货地址组织不匹配");
                            errorList.add(importOrderRequest);
                        }
                        continue;
                    }

                    //查询客户信息
                    if (StringUtils.isNotBlank(orderSDO.getCustomerCode())) {
                        CustomerRequest request = new CustomerRequest();
                        request.setCode(orderSDO.getCustomerCode());
                        Result<CustomerSDO> result = customerQueryService.queryCustomer(request);
                        orderSDO.setCustomerName(result.getResult().getName());
                        orderSDO.setCustomerCode(result.getResult().getCode());

                    }
                    String factoryCode="";
                    String stockCode="";
                    //查询逻辑仓信息
                    if (StringUtils.isNotBlank(importOrderRequests.get(0).getWareHouseCode())) {
                        CargoZoneByOutCodesRequest byIdRequest = new CargoZoneByOutCodesRequest();
                        byIdRequest.setCodes(Arrays.asList(importOrderRequests.get(0).getWareHouseCode()));
                        SearchCargoZoneListByOutCodeResponse warehouseInfoResult = unifiedInventoryService.searchCargoZoneListByOutCode(byIdRequest);
                       if(CollectionUtils.isNotEmpty(warehouseInfoResult.getResult())) {
                           WarehouseInfo warehouseInfo = warehouseInfoResult.getResult().get(0);
                           if (Objects.nonNull(warehouseInfo)) {
                               orderSDO.setWareHouseName(warehouseInfo.getName());
                               orderSDO.setWareHouseCode(warehouseInfo.getId());
                               orderSDO.setWareHouseOutCode(warehouseInfo.getCode());
                               factoryCode = warehouseInfo.getSapFactoryCode();
                               stockCode = warehouseInfo.getWarehouseCode();
                           }
                       }
                    }

                    //设置订单标识
                    SetOrderTag.getOrderTag(importOrderRequests.get(0).getOrderType().trim(), orderSDO);
                    if(StringUtils.isBlank(orderSDO.getFromSys())) {
                        orderSDO.setFromSys("APP_OTS");
                    }
                    OrderOutCodeAssmeble.assembleOutCode(orderSDO);
                    String id = orderWriteRepository.saveOrder(orderSDO);

                    //创建销售明细单
                    List<OrderLineSDO> orderLineSDOS = new ArrayList<>();
                    int i = 1;
                    //子单有错误时
                    List<Boolean> hasErrors = Lists.newArrayList();
                    try {
                        for (ImportOrderRequest it : importOrderRequests) {
                            OrderLineSDO orderLineSDO = OrderLineSDO.builder()
                                    // .sal(it.getSaleUnit())
                                    .serialNumber(String.valueOf(i * 10))
                                    .status(OrderStatus.BEFORE_SUBMIT.getCode())//待提交
                                    .mainOrderBizId(orderSDO.getOrderBizId())
                                    .remark(it.getOrderLineRemark())
                                    .shippingWarehouseCode(orderSDO.getWareHouseCode())
                                    .shippingWarehouseOutCode(orderSDO.getWareHouseOutCode())
                                    .shippingWarehouseName(orderSDO.getWareHouseName())
                                    .deliveryFactoryCode(factoryCode)
                                    .stockCode(stockCode)
                                    // .saleUnit(it.getSaleUnit())
                                    .mainOrderId(id)
                                    .customerCode(orderSDO.getCustomerCode()).build();
                            String totalAmount = it.getTotalAmount();
                            String orderTag = orderSDO.getOrderTag();
                            //识别子单标签
                            if (StringUtils.isNotBlank(orderTag)) {
                                if (SetOrderTag.EXCHANGE.equals(orderTag)) {
                                    orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                                }
                                if (SetOrderTag.RETURN.equals(orderTag)) {
                                    orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                                }
                                if (SetOrderTag.NORMAL.equals(orderTag)) {
                                    orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                                }
                            }

                            Long unitPrice = null;
                            BigDecimal mul = new BigDecimal("100");
                            if (it.getUnitPrice() != null) {
                                BigDecimal price = new BigDecimal(it.getUnitPrice());
                                unitPrice = price.multiply(mul).longValue();
                            }

                            ScItemSDO scItemSDO = ScItemSDO.builder()
                                    .scItemId(it.getScItecmId())
                                    .unitPrice(unitPrice)
                                    .quantity(Integer.parseInt(it.getQuantity()))
                                    .saleUnit(it.getSaleUnit()).build();

                            i++;
                            orderLineSDO.setScItemSDO(scItemSDO);

                            //查询货品信息
                            SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                            SearchReqDTO searchReqDTO = new SearchReqDTO();
                            List<String> list = new ArrayList<>();
                            list.add(orderLineSDO.getScItemSDO().getScItemId());
                            searchReqDTO.setOuterIdList(list);
                            searchScItemRequest.setSearchReqDTO(searchReqDTO);
                            Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
                            if (listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())) {
                                scItemSDO.setScItemTitle(listResult.getResult().get(0).getTitle());
                                scItemSDO.setScItemId(listResult.getResult().get(0).getScItemId());
                                //scItemSDO.setUnit(listResult.getResult().get(0).getUnit());
                            }
                            //库存单位，不为空以填写为准，否则系统默认库存单位
                            String inventoryUnit = String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName"));
                            QuerySaleOrderLine line = new QuerySaleOrderLine();
                            line.setGoodsId(scItemSDO.getScItemId());
                            line.setGoodsName(scItemSDO.getScItemTitle());
                            line.setQuantity(String.valueOf(scItemSDO.getQuantity()));
                            line.setSaleUnit(StringUtils.isBlank(scItemSDO.getSaleUnit()) ? inventoryUnit : scItemSDO.getSaleUnit());
                            line.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                            line.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));

                            //查询货品销售单位列表
                            QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemSDO.getScItemId()).build();
                            querySaleUnitRequest.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
                            querySaleUnitRequest.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
                            querySaleUnitRequest.setUnitConvert("1");
                            Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
                            List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
                            Map<String, SelectCombox> unitMap = new HashMap<>();
                            Nullable.stream(saleUnitListResult).forEach(t -> {
                                unitMap.put(t.getValue(), t);
                            });

                            SelectCombox selected;
                            if (StringUtils.isNotBlank(scItemSDO.getSaleUnit())) {
                                selected = unitMap.get(scItemSDO.getSaleUnit());
                            } else {
                                selected = unitMap.get(inventoryUnit);
                            }

                            if (selected != null) {
                                scItemSDO.setUnitConvert(selected.getExt());
                            }

                            QuerySaleOrderLineRequest request = new QuerySaleOrderLineRequest();
                            request.setId(id);
                            request.setSaleOrderLines(Collections.singletonList(line));
                            List<QuerySaleOrderLine> querySaleOrderLines = orderLineQueryServiceRepository.queryScItemInfo(request);
                            if (CollectionUtils.isNotEmpty(querySaleOrderLines) && null != querySaleOrderLines.get(0)) {
                                scItemSDO.setScItemId(querySaleOrderLines.get(0).getGoodsId());
                                scItemSDO.setScItemTitle(querySaleOrderLines.get(0).getGoodsName());
                                scItemSDO.setScItemOutCode(it.getScItecmId());
                                if (null != querySaleOrderLines.get(0).getUnitConvert()) {
                                    scItemSDO.setUnitChangeRelation(String.valueOf(querySaleOrderLines.get(0).getUnitConvert()));
                                }
                                scItemSDO.setInventoryUnitCode(querySaleOrderLines.get(0).getInventoryUnitCode());
                                scItemSDO.setInventoryUnitName(querySaleOrderLines.get(0).getInventoryUnit());
                                if (scItemSDO.getUnitPrice() == null) {
                                    scItemSDO.setUnitPrice(querySaleOrderLines.get(0).getUnitPrice() == null ? null : Long.valueOf(querySaleOrderLines.get(0).getUnitPrice()));
                                }

                                if (SaleOrderTag.CASH_ORDER.getCode().equals(orderSDO.getOrderType()) || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(orderSDO.getOrderType())) {
                                    Map<String, String> features = new HashMap<>();
                                    //价格判断 如果 货品+单位获取的价格错误, 则需要抛错;
//                                    if (querySaleOrderLines.get(0).getUnitPrice() == null || "-999".equals(querySaleOrderLines.get(0).getUnitPrice()) ){
//                                        it.setErrorMessage(it.getScItecmId() + "价格获取异常");
//                                        errorList.add(it);
//                                        hasErrors.add(false);
//                                        continue;
//                                    }
                                    if (null != unitPrice) {
                                        //手工单价
                                        BigDecimal bUnitPrice = new BigDecimal(unitPrice);
                                        features.put(SaleOrderConstants.MANUAL_PRICE, String.valueOf(unitPrice));
                                        //常规单价
                                        scItemSDO.setUnitPrice(querySaleOrderLines.get(0).getUnitPrice() == null ? null : Long.valueOf(querySaleOrderLines.get(0).getUnitPrice()));
                                        if (null != scItemSDO.getQuantity()) {
                                            //手工总金额
                                            BigDecimal bQuantity = new BigDecimal(scItemSDO.getQuantity());
                                            Long manualTotalAmount = bUnitPrice.multiply(bQuantity).longValue();
                                            features.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, String.valueOf(manualTotalAmount));
                                        }
                                    }
                                    if (StringUtils.isNotBlank(totalAmount)) {
                                        BigDecimal importLineTotalAmount = new BigDecimal(totalAmount).multiply(new BigDecimal("100"));

                                        int importLineQuantity = scItemSDO.getQuantity() == null ? 1 : scItemSDO.getQuantity();
                                        features.put(SaleOrderConstants.MANUAL_TOTAL_AMOUNT, String.valueOf(importLineTotalAmount.setScale(0, RoundingMode.HALF_UP)));

                                        features.put(SaleOrderConstants.MANUAL_PRICE, String.valueOf(importLineTotalAmount.divide(new BigDecimal(importLineQuantity), 0, RoundingMode.HALF_UP)));
                                    }
                                    if (MapUtils.isEmpty(orderLineSDO.getFeatures())) {
                                        orderLineSDO.setFeatures(features);
                                    } else {
                                        orderLineSDO.getFeatures().putAll(features);
                                    }
                                }

                                scItemSDO.setCategoryCode(querySaleOrderLines.get(0).getCategoryCode());
                                scItemSDO.setCategoryDesc(querySaleOrderLines.get(0).getCategoryDesc());
                                scItemSDO.setCategoryChildCode(querySaleOrderLines.get(0).getCategoryChildCode());
                                scItemSDO.setCategoryChildDesc(querySaleOrderLines.get(0).getCategoryChildDesc());

                                scItemSDO.setFirstCategoryCode(querySaleOrderLines.get(0).getFirstCategoryCode());
                                scItemSDO.setFirstCategoryDesc(querySaleOrderLines.get(0).getFirstCategoryDesc());
                                scItemSDO.setSecondCategoryCode(querySaleOrderLines.get(0).getSecondCategoryCode());
                                scItemSDO.setSecondCategoryDesc(querySaleOrderLines.get(0).getSecondCategoryDesc());

                                orderLineSDO.setScItemSDO(scItemSDO);
                                //创建销售子订单
                                orderLineWriteRepository.save(orderLineSDO);
                            }
                            orderLineSDOS.add(orderLineSDO);
                            saveSuccessList.add(it);
                        }
                    } catch (Exception e) {
                        hasErrors.add(false);
                        importOrderRequests.stream().forEach(importOrderRequest -> {
                            importOrderRequest.setErrorMessage("创建销售订单失败");
                            errorList.add(importOrderRequest);
                        });
                    }
                    //如果 子单行价格报错了 或者失败了, 继续循环其他单子
                    if (hasErrors.contains(false)) {
                        log.error("OrderImportError:{}", JSON.toJSONString(importOrderRequests));
                        hasErrors.clear();
                        continue;
                    }

                    OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
                    orderQueryRequest.setId(id);
                    OrderQueryResponse response = orderQueryServiceRepository.query(orderQueryRequest);
                    if (Objects.nonNull(response) && StringUtils.isNotBlank(response.getId())) {
                        OrderSDO finalOrderSDO = SaveOrderConverter.respConverterSDO(response);
                        //记录创建操作日志
                        doOperateLog(finalOrderSDO, employeeGetCurrentLoginResponse, OrderOperateType.CREATE);

                        OrderWriteEntity orderWriteEntity = OrderWriteFactory.updateOrder(finalOrderSDO);
                        //modify by myw,at 20230309,for batch commit sap,end
                        Result<TradeMessageSDO> tradeMessageSDOResult = orderWriteEntity.submitOrderStatusSave();
                        if (Objects.nonNull(tradeMessageSDOResult.getResult()) && tradeMessageSDOResult.isSuccess() && Objects.nonNull(tradeMessageSDOResult.getResult())) {
                            tradeMessageSDOS.add(tradeMessageSDOResult.getResult());
                        }
                        //记录提交操作日志
                        doOperateLog(finalOrderSDO, employeeGetCurrentLoginResponse, OrderOperateType.SUBMIT);
                    }

                }
            }
            //add my myw,at 20230309,for batch commit sap,end
            if (CollectionUtils.isNotEmpty(tradeMessageSDOS)) {

                updateTask(tradeMessageSDOS, taskId);
                Map<String, String> map = new HashMap<>();
                map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());

                Boolean batchSendResp = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleBatchCreated", sequenceNo, sequenceNo, map);
                if (!batchSendResp) {
                    log.error("OrderWriteEntity_Batch_submitMQ_fail", JSON.toJSONString(tradeMessageSDOS));
                }
            }

        }
        //失败的条数
        log.info("orderImport_errorList:{}", JSON.toJSONString(errorList));
        Nullable.stream(errorList).forEach(resultList::add);
        //成功的条数
        log.info("orderImport_successList:{}", JSON.toJSONString(saveSuccessList));
        Nullable.stream(saveSuccessList).forEach(resultList::add);

        List<String> errCustomerReferenceNo = importOrderList.stream().filter(x -> StringUtils.isNotBlank(x.getErrorMessage()))
                .map(req -> req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo()).collect(Collectors.toList());
        log.info("orderImport_errCustomerReferenceNo:{}", JSON.toJSONString(errCustomerReferenceNo));
        log.info("orderImport_importOrderList:{}", JSON.toJSONString(importOrderList));
        importOrderList.stream().forEach(req -> {
            if (CollectionUtils.isNotEmpty(errCustomerReferenceNo) && StringUtils.isBlank(req.getErrorMessage()) && errCustomerReferenceNo.contains(req.getOrderType() + req.getOrganizationCode() + req.getProductGroupCode() + req.getChannelCode() + req.getReceiveAddressCode() + req.getCustomerReferenceNo())) {
                req.setErrorMessage("同主单的其他销售单行报错");
            }
        });
        return Result.success(importOrderList);
    }
    private Boolean checkExcelData(ImportOrderRequest importOrderRequest, ExcelImportOrderListRequest excelImportOrderListRequest, List<String> loginOrganizationCodes) {
        //校验订单数量
        if (StringUtils.isBlank(importOrderRequest.getQuantity())) {
            importOrderRequest.setErrorMessage("订单数量不能为空！");
            return false;
        }
        int quantityTmp = Integer.parseInt(importOrderRequest.getQuantity());
        if (quantityTmp <= 0 || quantityTmp > 10000000) {
            importOrderRequest.setErrorMessage("订单数量应在0到10000000之间");
            return false;
        }

        //校验导入订单类型
        if (StringUtils.isNotBlank(excelImportOrderListRequest.getOrderTag())) {
            Boolean flag = checkOrderType(excelImportOrderListRequest.getOrderTag(), importOrderRequest);
            if (!flag) {
                importOrderRequest.setErrorMessage("导入的订单类型不符");
                return false;
            }
        }

        //检验销售组织
        if (StringUtils.isBlank(importOrderRequest.getOrganizationCode())) {
            importOrderRequest.setErrorMessage("销售组织不能为空");
            return false;
        } else {
            if (!loginOrganizationCodes.contains(importOrderRequest.getOrganizationCode())) {
                importOrderRequest.setErrorMessage("销售组织不存在或权限不匹配");
                return false;
            }
        }

        //检验单据原因,只有退单的才校验
        if ("return".equals(excelImportOrderListRequest.getOrderTag())) {
            if (StringUtils.isBlank(importOrderRequest.getCreateReason())) {
                importOrderRequest.setErrorMessage("单据原因不能为空");
                return false;
            } else {
                boolean match = Stream.of(DocumentReasonEnum.values()).anyMatch(x -> x.getCode().equals(importOrderRequest.getCreateReason()));

                if (!match) {
                    importOrderRequest.setErrorMessage(importOrderRequest.getCreateReason() + "单据原因不匹配");
                    return false;
                }
            }
        }

        //校验客户参考日期 填写后需符合格式
        if (StringUtils.isNotBlank(importOrderRequest.getCustomerExpectDate())) {
            if (!DateUtils.isDateFormat(importOrderRequest.getCustomerExpectDate())) {
                importOrderRequest.setErrorMessage("客户参考日期格式不正确");
                return false;
            }
            Date expectDate = TimeUtil.parseYYYY_MM_dd(importOrderRequest.getCustomerExpectDate());
            if (Objects.isNull(expectDate)) {
                importOrderRequest.setErrorMessage("客户参考日期格式不正确");
                return false;
            }
            //时间校验
            Date firstTime = DateUtils.getFirstTime(new Date());
            if (expectDate.before(firstTime)) {
                importOrderRequest.setErrorMessage("客户期待参考日期不能早于当天日期");
                return false;
            }
        }

        //校验客户参考号
        if (StringUtils.isBlank(importOrderRequest.getCustomerReferenceNo())) {
            importOrderRequest.setErrorMessage("客户参考号不能为空");
            return false;
        } else {
            importOrderRequest.setCustomerReferenceNo(importOrderRequest.getCustomerReferenceNo().trim());
            if (importOrderRequest.getCustomerReferenceNo().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCustomerReferenceNo()).matches()) {
                importOrderRequest.setErrorMessage("客户参考号不能有特殊字符");
                return false;
            } else {
                return true;
            }
        }
    }

    private Boolean checkScItemUnit(ImportOrderRequest importOrderRequest, Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult) {
        //货品信息
        String scItemId = listResult.getResult().get(0).getScItemId();
        //库存单位，不为空以填写为准，否则系统默认库存单位
        String inventoryUnit = String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName"));
        //查询货品销售单位列表
        QuerySaleUnitRequest querySaleUnitRequest = QuerySaleUnitRequest.builder().scItemId(scItemId).build();
        querySaleUnitRequest.setInventoryUnit(String.valueOf(listResult.getResult().get(0).getFeatures().get("unit")));
        querySaleUnitRequest.setInventoryUnitCode(String.valueOf(listResult.getResult().get(0).getFeatures().get("unitName")));
        querySaleUnitRequest.setUnitConvert("1");
        Result<List<SelectCombox>> querySaleUnitList = forecastOrderLineQueryService.querySaleUnitList(querySaleUnitRequest);
        List<SelectCombox> saleUnitListResult = querySaleUnitList.getResult();
        Map<String, SelectCombox> unitMap = new HashMap<>();
        Nullable.stream(saleUnitListResult).forEach(t -> {
            unitMap.put(t.getValue(), t);
        });

        SelectCombox selected;
        if (StringUtils.isNotBlank(importOrderRequest.getSaleUnit())) {
            selected = unitMap.get(importOrderRequest.getSaleUnit());
        } else {
            selected = unitMap.get(inventoryUnit);
        }

        if (selected == null) {
            importOrderRequest.setErrorMessage(importOrderRequest.getScItecmId() + "货品单位不匹配");
            return false;
        }
        return true;
    }

    private Boolean checkOrderType(String orderTag, ImportOrderRequest importOrderRequest) {
        if (orderTag.equals(SetOrderTag.NORMAL)) {
            Map<String, String> normalMap = new HashMap<>();
            normalMap.put(SaleOrderTag.STD_ORDER.getCode(), SaleOrderTag.STD_ORDER.getCode());
            normalMap.put(SaleOrderTag.REPLENISH_ORDER.getCode(), SaleOrderTag.REPLENISH_ORDER.getCode());
            normalMap.put(SaleOrderTag.FREE_ORDER.getCode(), SaleOrderTag.FREE_ORDER.getCode());
            normalMap.put(SaleOrderTag.CAR_ORDER.getCode(), SaleOrderTag.CAR_ORDER.getCode());
            normalMap.put(SaleOrderTag.CASH_ORDER.getCode(), SaleOrderTag.CASH_ORDER.getCode());

            List<ImportOrderRequest> normalList = new ArrayList<>();
            //modify by myw,format
            if (normalMap.containsKey(importOrderRequest.getOrderType())) {
                normalList.add(importOrderRequest);
            }
            if (CollectionUtils.isEmpty(normalList)) {
                return false;
            }
        }
        if (orderTag.equals(SetOrderTag.RETURN)) {
            Map<String, String> returnMap = new HashMap<>();
            returnMap.put(SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode(), SaleOrderTag.LOGISTIC_RETURN_ORDER.getCode());
            returnMap.put(SaleOrderTag.STD_RETURN_ORDER.getCode(), SaleOrderTag.STD_RETURN_ORDER.getCode());

            List<ImportOrderRequest> returnList = new ArrayList<>();
            //modify by myw,format
            if (returnMap.containsKey(importOrderRequest.getOrderType())) {
                returnList.add(importOrderRequest);
            }
            if (CollectionUtils.isEmpty(returnList)) {
                return false;
            }
        }
        if (orderTag.equals(SetOrderTag.EXCHANGE)) {
            return importOrderRequest.getOrderType().equals(SaleOrderTag.EXCHANGE_ORDER.getCode());
        }
        return true;
    }

    private ImportOrderRequest excelCheckStock(ImportOrderRequest importOrderRequest) {

        //逻辑仓ID
        String warehouseId = null;
        //查询逻辑仓信息
        if (StringUtils.isNotBlank(importOrderRequest.getWareHouseCode())) {
            WmsQueryWarehouseZoneListRequest byIdRequest = new WmsQueryWarehouseZoneListRequest();
            byIdRequest.setCode(importOrderRequest.getWareHouseCode());
            WmsQueryWarehouseZoneListResponse warehouseInfoResult = unifiedInventoryService.wmsQueryWarehouseZoneList(byIdRequest);
            if (CollectionUtils.isNotEmpty(warehouseInfoResult.getResult()) && Objects.nonNull(warehouseInfoResult.getResult().get(0))) {
                warehouseId = warehouseInfoResult.getResult().get(0).getId();
            }
        }

        //查询货品信息
        SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
        SearchReqDTO searchReqDTO = new SearchReqDTO();
        List<String> list = new ArrayList<>();
        if (StringUtils.isNotBlank(importOrderRequest.getScItecmId())) {
            list.add(importOrderRequest.getScItecmId());
            searchReqDTO.setOuterIdList(list);
        }
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItem(searchScItemRequest);
        if (CollectionUtils.isNotEmpty(listResult.getResult()) && Objects.isNull(listResult.getResult().get(0))) {
            importOrderRequest.setErrorMessage("未查到对应货品信息");
        } else {
            //校验库存
            GetListWarehouseStockRequest getRequest = new GetListWarehouseStockRequest();
            getRequest.setWarehouseAreaId(warehouseId);
            getRequest.setType("1");
            String scItemId = listResult.getResult().get(0).getScItemId();
            getRequest.setGoodsId(scItemId);
            Result<List<WarehouseInventory>> listWarehouseStock = crUnifiedInventoryService.getListWarehouseStock(getRequest);
            if (CollectionUtils.isEmpty(listWarehouseStock.getResult())) {
                importOrderRequest.setErrorMessage("仓库中未查到对应货品" + importOrderRequest.getScItecmId());
            } else {
                WarehouseInventory warehouseInventory = listWarehouseStock.getResult().get(0);
                int quantity = Integer.parseInt(importOrderRequest.getQuantity());
                if (null == warehouseInventory.getAvailableQuantity() || quantity > warehouseInventory.getAvailableQuantity()) {
                    importOrderRequest.setErrorMessage("库存不足货品编码" + importOrderRequest.getScItecmId());
                }
            }
        }
        return importOrderRequest;
    }

    public OrderSDO queryOrderSDO(String id) {
        OrderQueryRequest request = new OrderQueryRequest();
        request.setId(id);
        return orderQueryServiceRepository.querySingle(request);
    }

    /**
     * 获取 登录人 所属销售组织code
     *
     * @param type
     * @return
     */
    private List<OrganizationSDO> getLoginOrganizationCode(Integer type) {
        EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
        String relatedOrganizationId = employeeGetCurrentLoginResponse.getRelatedOrganizationId();
        IdQueryRequest request = new IdQueryRequest();
        request.setId(relatedOrganizationId);
        request.setType(type);
        Result<List<OrganizationSDO>> loginEmployOrganizationPermissions = organizationQueryService.getDownQueryOrganization(request);
        if (ObjectUtils.isEmpty(loginEmployOrganizationPermissions)) {
            return new ArrayList<>();
        }
        List<OrganizationSDO> result = loginEmployOrganizationPermissions.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result;
    }

    /**
     * 查询 销售组织的 业务渠道
     *
     * @param ids
     * @return
     */
    private List<String> businessChannelCodes(List<String> ids) {
        GetOrgChannelRelationByOrgId2Request request = GetOrgChannelRelationByOrgId2Request.builder().ids(ids).build();
        Result<List<OrganizationChannelRelationSDO>> orgChannelRelationByOrgId2 = crPlatformEnhanceService.getOrgChannelRelationByOrgId2(request);
        if (ObjectUtils.isEmpty(orgChannelRelationByOrgId2)) {
            return new ArrayList<>();
        }
        List<OrganizationChannelRelationSDO> result = orgChannelRelationByOrgId2.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result.stream().map(OrganizationChannelRelationSDO::getOutCode).collect(Collectors.toList());
    }

    /**
     * 获取登录人 负责的收货地址code
     *
     * @param addressCode                     所有 需要校验的code
     * @param employeeGetCurrentLoginResponse 登陆人
     * @return 符合要求的code
     */
    private Map<String, List<CustomerAddressSDO>> addressLists(List<String> addressCode, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {
        CustomerAddressBatchRequest addressBatchRequest = CustomerAddressBatchRequest.builder().addressCodes(addressCode).build();
        String relatedOrganizationId = employeeGetCurrentLoginResponse.getRelatedOrganizationId();
        switch (employeeGetCurrentLoginResponse.getRelatedOrganizationType()) {
            case "103":
                // 分子公司
                addressBatchRequest.setOrgBussinessUnitCode(relatedOrganizationId);
                break;
            case "104":
                // 销售组织
                addressBatchRequest.setOrgSaleOrganizationCode(relatedOrganizationId);
                break;
            case "105":
                // 销售渠道
                addressBatchRequest.setOrgSaleChannelCode(relatedOrganizationId);
                break;
            case "106":
                // 销售部门
                addressBatchRequest.setOrgSaleDepartmentCode(relatedOrganizationId);
                break;
        }
        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.batchQueryCustomerAddress(addressBatchRequest);
        List<CustomerAddressSDO> result = CollectionUtils.isEmpty(listResult.getResult()) ? new ArrayList<>() : listResult.getResult();
        return result.stream().collect(Collectors.groupingBy(CustomerAddressSDO::getAddressCode));
    }

    private Map<String, List<CustomerAddressSDO>> addressUniKeyLists(List<String> addressCode, EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {

        CustomerAddressBatchRequest addressBatchRequest = CustomerAddressBatchRequest.builder().addressCodes(addressCode).build();

        String relatedOrganizationId = employeeGetCurrentLoginResponse.getRelatedOrganizationId();
        switch (employeeGetCurrentLoginResponse.getRelatedOrganizationType()) {
            case "103":
                // 分子公司
                addressBatchRequest.setOrgBussinessUnitCode(relatedOrganizationId);
                break;
            case "104":
                // 销售组织
                addressBatchRequest.setOrgSaleOrganizationCode(relatedOrganizationId);
                break;
            case "105":
                // 销售渠道
                addressBatchRequest.setOrgSaleChannelCode(relatedOrganizationId);
                break;
            case "106":
                // 销售部门
                addressBatchRequest.setOrgSaleDepartmentCode(relatedOrganizationId);
                break;
        }

        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.batchQueryCustomerAddress(addressBatchRequest);
        List<CustomerAddressSDO> result = CollectionUtils.isEmpty(listResult.getResult()) ? new ArrayList<>() : listResult.getResult();
        Map<String, List<CustomerAddressSDO>> collect = result.stream().collect(Collectors.groupingBy(o -> o.getAddressCode() + "-" + o.getOrgSaleOrganizationCode()));

        return collect;
    }

    /**
     * 登录人导入 权限校验
     *
     * @param importOrderRequest
     * @param loginOrganizationCode
     * @param channelCode
     * @param warehouseCodes
     * @param addressCodes
     * @return
     */
    private String importCheckErrorMessage(ImportOrderRequest importOrderRequest,
                                           List<String> loginOrganizationCode,
                                           List<String> channelCode,
                                           List<String> warehouseCodes,
                                           List<String> addressCodes) {
        if (StringUtils.isBlank(importOrderRequest.getCustomerReferenceNo())) {
            return "客户参考号不能为空";
        } else {
            importOrderRequest.setCustomerReferenceNo(importOrderRequest.getCustomerReferenceNo().trim());
            if (importOrderRequest.getCustomerReferenceNo().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCustomerReferenceNo()).matches()) {
                return "客户参考号不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getOrderType())) {
            return "销售订单类型不能为空";
        } else {
            importOrderRequest.setOrderType(importOrderRequest.getOrderType().trim());
            if (importOrderRequest.getOrderType().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getOrderType()).matches()) {
                return "销售订单类型不能有特殊字符";
            }
        }

        if (StringUtils.isBlank(importOrderRequest.getOrganizationCode())) {
            return "销售组织不能为空";
        } else {
            importOrderRequest.setOrganizationCode(importOrderRequest.getOrganizationCode().trim());
            if (importOrderRequest.getOrganizationCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getOrganizationCode()).matches()) {
                return "销售组织不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getChannelCode())) {
            return "业务渠道不能为空";
        } else {
            importOrderRequest.setChannelCode(importOrderRequest.getChannelCode().trim());
            if (importOrderRequest.getChannelCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getChannelCode()).matches()) {
                return "业务渠道不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getReceiveAddressCode())) {
            return "收货地址不能为空";
        } else {
            importOrderRequest.setReceiveAddressCode(importOrderRequest.getReceiveAddressCode().trim());
            if (importOrderRequest.getReceiveAddressCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getReceiveAddressCode()).matches()) {
                return "收货地址不能有特殊字符";
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getWareHouseCode())) {
            return "发货仓不能为空";
        } else {
            importOrderRequest.setWareHouseCode(importOrderRequest.getWareHouseCode().trim());
            if (importOrderRequest.getWareHouseCode().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getWareHouseCode()).matches()) {
                return "发货仓不能有特殊字符";
            }
        }
        //2023.02.27 收货仓 换货订单校验
        if (StringUtils.isNotBlank(importOrderRequest.getOrderType()) &&
                SaleOrderTag.EXCHANGE_ORDER.getCode().equals(importOrderRequest.getOrderType().trim())) {
            if (StringUtils.isBlank(importOrderRequest.getReceiveWareHouseCode())) {
                return "收货仓不能为空";
            } else {
                importOrderRequest.setReceiveWareHouseCode(importOrderRequest.getReceiveWareHouseCode().trim());
                if (importOrderRequest.getReceiveWareHouseCode().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getReceiveWareHouseCode()).matches()) {
                    return "收货仓不能有特殊字符";
                }
            }
        }
        if (StringUtils.isBlank(importOrderRequest.getQuantity()) || !StringUtils.isNumeric(importOrderRequest.getQuantity())) {
            return "数量无效";
        } else {
            importOrderRequest.setQuantity(importOrderRequest.getQuantity().trim());
            if (importOrderRequest.getQuantity().contains(" ")
                    || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getQuantity()).matches()) {
                return "数量不能有特殊字符";
            }
        }
        // 订单类型编码：
        //ZOR2：标准销售订单
        //ZFD2：免费销售订单
        //ZBV：现金销售订单
        //ZRE2：标准退货订单
        // 成本中心 免费订单类型必填
        if (SaleOrderTag.FREE_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCostCenter())) {
                return "免费订单 成本中心不能为空";
            } else {
                importOrderRequest.setCostCenter(importOrderRequest.getCostCenter().trim());
                if (importOrderRequest.getCostCenter().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCostCenter()).matches()) {
                    return "免费订单 成本中心不能有特殊字符";
                }
            }
        }
        // 现金客户名称 现金订单类型必填
        if (SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCashCustomerName())) {
                return "现金订单 成现金客户名称不能为空";
            } else {
                importOrderRequest.setCashCustomerName(importOrderRequest.getCashCustomerName().trim());
                if (importOrderRequest.getCashCustomerName().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCashCustomerName()).matches()) {
                    return "现金订单 成现金客户名称不能有特殊字符";
                }
            }
        }
        // 单价 退货订单&现金订单必填
        boolean priceBoolean = SaleOrderTag.CASH_ORDER.getCode().equals(importOrderRequest.getOrderType()) || SaleOrderTag.STD_RETURN_ORDER.getCode().equals(importOrderRequest.getOrderType().trim());
        if (priceBoolean && (StringUtils.isBlank(importOrderRequest.getUnitPrice()) && StringUtils.isBlank(importOrderRequest.getTotalAmount()))) {
            return "退货订单&现金订单 单价和总价不能同时为空";
        } else {
            if (StringUtils.isNotBlank(importOrderRequest.getUnitPrice()) && !PATTERN_NUMERIC.matcher(importOrderRequest.getUnitPrice()).matches()) {
                return "单价无效";
            }
        }
        // 标准退货 订单原因必须输入
        if (SaleOrderTag.STD_RETURN_ORDER.getCode().equals(importOrderRequest.getOrderType())) {
            if (StringUtils.isBlank(importOrderRequest.getCreateReason())) {
                return "标准退货订单 单据原因不能为空";
            } else {
                importOrderRequest.setCreateReason(importOrderRequest.getCreateReason().trim());
                if (importOrderRequest.getCreateReason().contains(" ")
                        || PATTERN_SPECIAL_STRING.matcher(importOrderRequest.getCreateReason()).matches()) {
                    return "标准退货订单 单据原因不能有特殊字符";
                }
            }
        }

        //校验主单备注信息   长度小于等于50
        if (StringUtils.isNotBlank(importOrderRequest.getOrderRemark()) && importOrderRequest.getOrderRemark().length() > 256) {
            return "主单备注信息长度不能超过255个字";
        }
        //校验子单备注信息   长度小于等于50
        if (StringUtils.isNotBlank(importOrderRequest.getOrderLineRemark()) && importOrderRequest.getOrderLineRemark().length() > 256) {
            return "子单备注详情信息长度不能超过255个字";
        }

        // 校验 导入数据 不是登陆人所属销售组织 不允许导入
        if (!loginOrganizationCode.contains(importOrderRequest.getOrganizationCode())) {
            return "销售组织没有权限";
        }
        // 校验 导入数据 不是登陆人所属销售渠道 不允许导入
        if (!channelCode.contains(importOrderRequest.getChannelCode())) {
            return "业务渠道没有权限";
        }
        // 校验 导入数据 不是登陆人所管理客户地址 不允许导入
        if (!addressCodes.contains(importOrderRequest.getReceiveAddressCode())) {
            return "收货地址没有权限";
        }
        // 校验 导入数据 不是登陆人所管理仓库 不允许导入
        if (!warehouseCodes.contains(importOrderRequest.getWareHouseCode())) {
            return "发货仓没有权限";
        }
        //2023.02.27 校验换货订单收货仓
        if (SaleOrderTag.EXCHANGE_ORDER.getCode().equals(importOrderRequest.getOrderType()) &&
                !warehouseCodes.contains(importOrderRequest.getReceiveWareHouseCode())) {
            return "收货仓没有权限";
        }

        // 导入 的业务渠道 和客户 不一致 也不能导入
        QueryAddressRequest queryAddressRequest = new QueryAddressRequest();
        queryAddressRequest.setAddressCode(importOrderRequest.getReceiveAddressCode());
        queryAddressRequest.setChannelCode(importOrderRequest.getChannelCode());
        Result<List<CustomerAddressSDO>> listResult = customerAddressQueryService.pageQueryCustomerAddress(queryAddressRequest);
        if (ObjectUtils.isEmpty(listResult)) {
            return "业务渠道 和客户不一致";
        }
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            return "业务渠道 和客户不一致";
        }
        List<CustomerAddressSDO> collect = listResult.getResult().stream().filter(customerAddressSDO ->
                StringUtils.isNotBlank(customerAddressSDO.getPrincipal())
        ).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect) || Objects.isNull(collect.get(0))) {
            return "客户收货地址未匹配到 对应的负责人";
        }
        return null;
    }

    /**
     * 校验 商品 是否可用
     *
     * @param outerId
     * @return
     */
    private Boolean checkScItemStatus(String outerId) {
        SearchScItemByDBWhenDegradedRequest searchScItemRequest = new SearchScItemByDBWhenDegradedRequest();
        SearchReqDTO searchReqDTO = new SearchReqDTO();
        List<String> list = new ArrayList<>();
        list.add(outerId);
        searchReqDTO.setOuterIdList(list);
        searchScItemRequest.setSearchReqDTO(searchReqDTO);
        //查询货品信息
        Result<List<com.epoch.app.bcorder.model.dto.ScItemSDO>> listResult = baseDataService.searchScItemByDBWhenDegraded(searchScItemRequest);
        if (ObjectUtils.isEmpty(listResult.getResult())) {
            return null;
        }
        List<com.epoch.app.bcorder.model.dto.ScItemSDO> result = listResult.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        return result.get(0).getStatus() == 1;
    }

    /**
     * 查询登录人 的 仓库权限
     *
     * @return
     */
    private List<String> getWarehouseCodes() {
        QueryCargoZoneListWithAccessRequest cargoZoneListRequest =
                QueryCargoZoneListWithAccessRequest.builder()
                        .model(3)
                        .status(1)
                        .typeList(Stream.of(3, 4, 6).collect(Collectors.toList()))
                        .build();
        // 获取登陆人 仓库权限
        QueryCargoZoneListWithAccessResponse searchCargoZoneListForPageResponse = bcOrderService.queryCargoZoneListWithAccess(cargoZoneListRequest);
        if (ObjectUtils.isEmpty(searchCargoZoneListForPageResponse)) {
            return new ArrayList<>();
        }
        List<WarehouseInfo> result = searchCargoZoneListForPageResponse.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        return result.stream().map(WarehouseInfo::getCode).collect(Collectors.toList());

    }

    /**
     * 设置信贷检查情况
     *
     * @param features
     * @param creditCheckStatus
     */
    private void setCreditCheck(Map<String, String> features, String creditCheckStatus) {
        String checkStatusName = "未执行信贷";
        if (StringUtils.isNotEmpty(creditCheckStatus)) {
            features.put(SaleOrderConstants.CREDIT_CHECK_STATUS, creditCheckStatus);
            features.put(SaleOrderConstants.CREDIT_CHECK_CODE,creditCheckStatus.split("\\-")[0]);
            if ("A".equals(creditCheckStatus)) {
                checkStatusName = "已同意";
            } else if ("B".equals(creditCheckStatus)) {
                checkStatusName = "信贷冻结";
            } else if ("C".equals(creditCheckStatus)) {
                checkStatusName = "信贷部分批准";
            } else if ("D".equals(creditCheckStatus)) {
                checkStatusName = "信贷批准";
            } else {
                checkStatusName = creditCheckStatus;
            }
        }
        features.put(SaleOrderConstants.CREDIT_CHECK_STATUS_NAME, checkStatusName);
    }

    /**
     * sap报文里的订单id转换成内部主键id  sap: 1开头 中间补0  总长度10
     *
     * @param sapOrderId
     * @return
     */
    public static String convertTradeOrderId(String sapOrderId) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(sapOrderId)) {
            return sapOrderId.trim().length() == 10 ? sapOrderId.trim().replaceFirst("^10+", "")
                    : sapOrderId.trim();
        }
        return null;
    }

    /**
     * 根据登录人信息获取货品经营范围
     *
     * @return
     */
    private List<ScItemManageRange> searchScItemManageRange() {
        Result<List<ScItemManageRange>> search = scItemManageRangeReadService.searchWithPermission();
        return Optional.ofNullable(search).map(Result::getResult).orElse(null);
    }

    //校验是否在货品范围内
    private String checkScItemManageRange(List<ScItemManageRange> scItemManageRanges, String scItemCode) {
        //是否全部禁用
        boolean allDisabled = scItemManageRanges.stream().allMatch(x -> ScItemManageRangeStatus.DISABLED.getValue().equals(x.getStatus()));
        if (allDisabled) {
            return null;
        }
        //按销售组织分组
        Map<String, List<ScItemManageRange>> map = scItemManageRanges.stream().collect(Collectors.groupingBy(ScItemManageRange::getSaleOrgId));
        //多个销售组织时 排除掉货品范围全部禁用的
        if (map.size() > 1) {
            map.values().forEach(ranges -> {
                boolean disabled = ranges.stream().allMatch(x -> ScItemManageRangeStatus.DISABLED.getValue().equals(x.getStatus()));
                if (disabled) {
                    scItemManageRanges.removeAll(ranges);
                }
            });
        }
        //判断是否在经营范围内
        List<ScItemManageRange> matchList = scItemManageRanges.stream().filter(x -> x.getScItemCode().equals(scItemCode)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(matchList)) {
            return "不在分子公司经营货品范围内";
        } else {
            boolean enable = matchList.stream().anyMatch(range -> ScItemManageRangeStatus.ENABLE.getValue().equals(range.getStatus()));
            if (!enable) {
                return "分子公司经营货品范围内为禁用状态";
            }
            return null;
        }
    }

}

